Nutz:基于ASM的Nut.Aop实现 博客分类: Nutz AOPJavaGoogleIDEASSH
程序员文章站
2024-02-04 17:12:04
...
Nutz: 一个很不错的SSH替代方案
http://code.google.com/p/nutz/
研究了一段时间了, 整个项目现时只依赖javassist.
但是,javassist的确很大,300多k, 整个nutz才500k, 有喧宾夺主之意.
而, nutz依赖javassist只有Aop.
故, 我在闲暇之余, 用asm 3.2实现了nutz的aop部分.
实现效果: 约30K, 压缩后15k, 加上asm 3.2的43k, 加起来不到60K. (*^__^*) 嘻嘻……
换句话说, 如果换上这个实现, nutz+asm 才 640k左右. O(∩_∩)O哈哈~ 狂笑中
整个aop的实现, 分成几个部分:
1. 写入模板字段
2. 继承父类的构造方法
3. 覆写需要aop拦截的方法
4. 写入模板方法
5. 生成类的二进制数据, 交给ClassLoader生成Class实例
6. 注入模板字段的值
完成!
代码在: http://code.google.com/p/nutzlab/source/browse/#svn/trunk/Nutz.Aop-ASM
或者可以在附件中找到源码. 版本rev 81
代码片段1:
代码片段2(写入其中一个模板方法):
好. 欢迎拍砖. 狠狠地拍!!
http://code.google.com/p/nutz/
研究了一段时间了, 整个项目现时只依赖javassist.
但是,javassist的确很大,300多k, 整个nutz才500k, 有喧宾夺主之意.
而, nutz依赖javassist只有Aop.
故, 我在闲暇之余, 用asm 3.2实现了nutz的aop部分.
实现效果: 约30K, 压缩后15k, 加上asm 3.2的43k, 加起来不到60K. (*^__^*) 嘻嘻……
换句话说, 如果换上这个实现, nutz+asm 才 640k左右. O(∩_∩)O哈哈~ 狂笑中
整个aop的实现, 分成几个部分:
1. 写入模板字段
2. 继承父类的构造方法
3. 覆写需要aop拦截的方法
4. 写入模板方法
5. 生成类的二进制数据, 交给ClassLoader生成Class实例
6. 注入模板字段的值
完成!
代码在: http://code.google.com/p/nutzlab/source/browse/#svn/trunk/Nutz.Aop-ASM
或者可以在附件中找到源码. 版本rev 81
代码片段1:
public byte[] toByteArray(){ addField(); addConstructors(); addAopMethods(); enhandMethod(); return cw.toByteArray(); }
代码片段2(写入其中一个模板方法):
static void addMethod_before(ClassVisitor cv, String _Nut_myName){ MethodVisitor mv = cv.visitMethod(ACC_PRIVATE + ACC_VARARGS, "_Nut_before", "(I[Ljava/lang/Object;)Z", null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, _Nut_myName, "_$$Nut_methodArray", "[Ljava/lang/reflect/Method;"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(AALOAD); mv.visitVarInsn(ASTORE, 3); mv.visitFieldInsn(GETSTATIC, _Nut_myName, "_$$Nut_methodInterceptorList", "[Ljava/util/List;"); mv.visitVarInsn(ILOAD, 1); mv.visitInsn(AALOAD); mv.visitVarInsn(ASTORE, 4); mv.visitInsn(ICONST_1); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;"); mv.visitVarInsn(ASTORE, 7); Label l0 = new Label(); mv.visitJumpInsn(GOTO, l0); Label l1 = new Label(); mv.visitLabel(l1); mv.visitFrame(F_FULL, 8, new Object[] { _Nut_myName, INTEGER, "[Ljava/lang/Object;", "java/lang/reflect/Method", "java/util/List", INTEGER, TOP, "java/util/Iterator" }, 0, new Object[] {}); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "org/nutz/aop/MethodInterceptor"); mv.visitVarInsn(ASTORE, 6); mv.visitVarInsn(ILOAD, 5); mv.visitVarInsn(ALOAD, 6); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEINTERFACE, "org/nutz/aop/MethodInterceptor", "beforeInvoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Z"); mv.visitInsn(IAND); mv.visitVarInsn(ISTORE, 5); mv.visitLabel(l0); mv.visitFrame(F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z"); mv.visitJumpInsn(IFNE, l1); mv.visitVarInsn(ILOAD, 5); mv.visitInsn(IRETURN); mv.visitMaxs(5, 8); mv.visitEnd(); }
好. 欢迎拍砖. 狠狠地拍!!