欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Nutz:基于ASM的Nut.Aop实现 博客分类: Nutz AOPJavaGoogleIDEASSH 

程序员文章站 2024-02-04 17:07:34
...
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:
	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();
	}


好. 欢迎拍砖. 狠狠地拍!!