https://www.oschina.net/code/snippet_1166271_24995
使用ASM改寫字節(jié)碼實現(xiàn)Aop荒典,是最快的Aop實現(xiàn)方式模庐。下面是一個簡單的示例,共學習使用鳄袍。
文章??http://my.oschina.net/u/1166271/blog/162796??詳細介紹了如何深入字節(jié)碼實現(xiàn)這一功能惠豺。
下面的代碼片段是使用?ASM?4.0?版本進行的字節(jié)碼操作洁墙,并且下面所有代碼為?Blog的配套代碼。
源碼與演示:源碼出處
1.?[代碼]目標類?
publicclassTestBean {
????publicvoidhalloAop() {
????????System.out.println("Hello Aop");
????}
}
2.?[代碼]Aop攔截器處理程序?
publicclassAopInterceptor {
????publicstaticvoidbeforeInvoke() {
????????System.out.println("before");
????};
????publicstaticvoidafterInvoke() {
????????System.out.println("after");
????};
}
3.?[代碼]生成字節(jié)碼并負責轉換為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]?[全屏預覽]
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);
????}
}