深入字節(jié)碼 -- 使用 ASM 實(shí)現(xiàn) AOP

https://www.oschina.net/code/snippet_1166271_24995

使用ASM改寫字節(jié)碼實(shí)現(xiàn)Aop,是最快的Aop實(shí)現(xiàn)方式。下面是一個簡單的示例,共學(xué)習(xí)使用。

文章??http://my.oschina.net/u/1166271/blog/162796??詳細(xì)介紹了如何深入字節(jié)碼實(shí)現(xiàn)這一功能。

下面的代碼片段是使用?ASM?4.0?版本進(jìn)行的字節(jié)碼操作,并且下面所有代碼為?Blog的配套代碼。

標(biāo)簽:?Hasor?ASM

源碼與演示:源碼出處

代碼片段(4)[全屏查看所有代碼]

1.?[代碼]目標(biāo)類?

publicclassTestBean {

????publicvoidhalloAop() {

????????System.out.println("Hello Aop");

????}

}

2.?[代碼]Aop攔截器處理程序?

publicclassAopInterceptor {

????publicstaticvoidbeforeInvoke() {

????????System.out.println("before");

????};

????publicstaticvoidafterInvoke() {

????????System.out.println("after");

????};

}

3.?[代碼]生成字節(jié)碼并負(fù)責(zé)轉(zhuǎn)換為Class類型的類裝載器?

classAopClassLoader extendsClassLoader implementsOpcodes {

????publicAopClassLoader(ClassLoader parent) {

????????super(parent);

????}

????publicClass<?> loadClass(String name) throwsClassNotFoundException {

????????if(!name.contains("TestBean_Tmp"))

????????????returnsuper.loadClass(name);

????????try{

????????????ClassWriter cw = newClassWriter(0);

????????????//

????????????InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("org/more/test/asm/TestBean.class");

????????????ClassReader reader = newClassReader(is);

????????????reader.accept(newAopClassAdapter(ASM4, cw), ClassReader.SKIP_DEBUG);

????????????//

????????????byte[] code = cw.toByteArray();

????????????//??????????? FileOutputStream fos = new FileOutputStream("c:\\TestBean_Tmp.class");

????????????//??????????? fos.write(code);

????????????//??????????? fos.flush();

????????????//??????????? fos.close();

????????????returnthis.defineClass(name, code, 0, code.length);

????????} catch(Throwable e) {

????????????e.printStackTrace();

????????????thrownewClassNotFoundException();

????????}

????}

}

4.?[代碼]ASM 改寫字節(jié)碼的完整程序?跳至?[1]?[2]?[3]?[4]?[全屏預(yù)覽]

classAopClassAdapter extendsClassVisitor implementsOpcodes {

????publicAopClassAdapter(intapi, ClassVisitor cv) {

????????super(api, cv);

????}

????publicvoidvisit(intversion, intaccess, String name, String signature, String superName, String[] interfaces) {

????????//更改類名,并使新類繼承原有的類。

????????super.visit(version, access, name + "_Tmp", signature, name, interfaces);

????????{

????????????MethodVisitor mv = super.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);

????????????mv.visitCode();

????????????mv.visitVarInsn(ALOAD, 0);

????????????mv.visitMethodInsn(INVOKESPECIAL, name, "<init>", "()V");

????????????mv.visitInsn(RETURN);

????????????mv.visitMaxs(1, 1);

????????????mv.visitEnd();

????????}

????}

????publicMethodVisitor visitMethod(intaccess, String name, String desc, String signature, String[] exceptions) {

????????if("<init>".equals(name))

????????????returnnull;

????????if(!name.equals("halloAop"))

????????????returnnull;

????????//

????????MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);

????????returnnewAopMethod(this.api, mv);

????}

}

classAopMethod extendsMethodVisitor implementsOpcodes {

????publicAopMethod(intapi, MethodVisitor mv) {

????????super(api, mv);

????}

????publicvoidvisitCode() {

????????super.visitCode();

????????this.visitMethodInsn(INVOKESTATIC, "org/more/test/asm/AopInterceptor", "beforeInvoke", "()V");

????}

????publicvoidvisitInsn(intopcode) {

????????if(opcode == RETURN) {

????????????mv.visitMethodInsn(INVOKESTATIC, "org/more/test/asm/AopInterceptor", "afterInvoke", "()V");

????????}

????????super.visitInsn(opcode);

????}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容