AOP 的利器:ASM 3.0 介绍二

改进 visitMethod 方法,增加对构造函数的处理:

Java代码 复制代码
  1. public MethodVisitor visitMethod(final int access, final String name,   
  2.     final String desc, final String signature, final String[] exceptions) {   
  3.     MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);   
  4.     MethodVisitor wrappedMv = mv;   
  5.     if (mv != null) {   
  6.         if (name.equals("operation")) {   
  7.             wrappedMv = new AddSecurityCheckMethodAdapter(mv);   
  8.         } else if (name.equals("<init>")) {   
  9.             wrappedMv = new ChangeToChildConstructorMethodAdapter(mv,   
  10.                 enhancedSuperName);   
  11.         }   
  12.     }   
  13.     return wrappedMv;   
  14. }  
public MethodVisitor visitMethod(final int access, final String name,
	final String desc, final String signature, final String[] exceptions) {
	MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
	MethodVisitor wrappedMv = mv;
	if (mv != null) {
		if (name.equals("operation")) {
			wrappedMv = new AddSecurityCheckMethodAdapter(mv);
		} else if (name.equals("<init>")) {
			wrappedMv = new ChangeToChildConstructorMethodAdapter(mv,
				enhancedSuperName);
		}
	}
	return wrappedMv;
}


 


这里 ChangeToChildConstructorMethodAdapter 将负责把 Account 的构造函数改造成其子类 Account$EnhancedByASM 的构造函数:

Java代码 复制代码
  1. class ChangeToChildConstructorMethodAdapter extends MethodAdapter {   
  2.     private String superClassName;   
  3.   
  4.     public ChangeToChildConstructorMethodAdapter(MethodVisitor mv,   
  5.         String superClassName) {   
  6.         super(mv);   
  7.         this.superClassName = superClassName;   
  8.     }   
  9.   
  10.     public void visitMethodInsn(int opcode, String owner, String name,   
  11.         String desc) {   
  12.         //调用父类的构造函数时   
  13.         if (opcode == Opcodes.INVOKESPECIAL && name.equals("<init>")) {    
  14.             owner = superClassName;   
  15.         }   
  16.         super.visitMethodInsn(opcode, owner, name, desc);//改写父类为superClassName   
  17.     }   
  18. }   
  19.    
class ChangeToChildConstructorMethodAdapter extends MethodAdapter {
	private String superClassName;

	public ChangeToChildConstructorMethodAdapter(MethodVisitor mv,
		String superClassName) {
		super(mv);
		this.superClassName = superClassName;
	}

	public void visitMethodInsn(int opcode, String owner, String name,
		String desc) {
		//调用父类的构造函数时
		if (opcode == Opcodes.INVOKESPECIAL && name.equals("<init>")) { 
			owner = superClassName;
		}
		super.visitMethodInsn(opcode, owner, name, desc);//改写父类为superClassName
	}
}
 



最后演示一下如何在运行时产生并装入产生的 Account$EnhancedByASM。 我们定义一个 Util 类,作为一个类工厂负责产生有安全检查的 Account 类:

Java代码 复制代码
  1. public class SecureAccountGenerator {   
  2.   
  3.     private static AccountGeneratorClassLoader classLoader =    
  4.         new AccountGeneratorClassLoade();   
  5.     private static Class secureAccountClass;   
  6.   
  7.     public Account generateSecureAccount() throws ClassFormatError,    
  8.         InstantiationException, IllegalAccessException {   
  9.         if (null == secureAccountClass) {               
  10.             ClassReader cr = new ClassReader("Account");   
  11.             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);   
  12.             ClassAdapter classAdapter = new AddSecurityCheckClassAdapter(cw);   
  13.             cr.accept(classAdapter, ClassReader.SKIP_DEBUG);   
  14.             byte[] data = cw.toByteArray();   
  15.             secureAccountClass = classLoader.defineClassFromClassFile(   
  16.                 "Account$EnhancedByASM",data);   
  17.         }   
  18.         return (Account) secureAccountClass.newInstance();   
  19.     }   
  20.   
  21.     private static class AccountGeneratorClassLoader extends ClassLoader {   
  22.         public Class defineClassFromClassFile(String className,   
  23.             byte[] classFile) throws ClassFormatError {   
  24.             return defineClass("Account$EnhancedByASM", classFile, 0, classFile.length());   
  25. |-------10--------20--------30--------40--------50--------60--------70--------80--------9|   
  26. |-------- XML error:  The previous line is longer than the max of 90 characters ---------|   
  27.         }   
  28.     }   
  29. }   
  30.    
public class SecureAccountGenerator {

	private static AccountGeneratorClassLoader classLoader = 
		new AccountGeneratorClassLoade();
	private static Class secureAccountClass;

	public Account generateSecureAccount() throws ClassFormatError, 
		InstantiationException, IllegalAccessException {
		if (null == secureAccountClass) {            
			ClassReader cr = new ClassReader("Account");
			ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
			ClassAdapter classAdapter = new AddSecurityCheckClassAdapter(cw);
			cr.accept(classAdapter, ClassReader.SKIP_DEBUG);
			byte[] data = cw.toByteArray();
			secureAccountClass = classLoader.defineClassFromClassFile(
				"Account$EnhancedByASM",data);
		}
		return (Account) secureAccountClass.newInstance();
	}

	private static class AccountGeneratorClassLoader extends ClassLoader {
		public Class defineClassFromClassFile(String className,
			byte[] classFile) throws ClassFormatError {
			return defineClass("Account$EnhancedByASM", classFile, 0, classFile.length());
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
		}
	}
}
 



静态方法 SecureAccountGenerator.generateSecureAccount() 在运行时动态生成一个加上了安全检查的 Account 子类。著名的 Hibernate 和 Spring 框架,就是使用这种技术实现了 AOP 的“无损注入”。





小结

最后,我们比较一下 ASM 和其他实现 AOP 的底层技术:


表 1. AOP 底层技术比较
AOP 底层技术 功能 性能 面向接口编程 编程难度
直接改写 class 文件 完全控制类 无明显性能代价 不要求 高,要求对 class 文件结构和 Java 字节码有深刻了解
JDK Instrument 完全控制类 无论是否改写,每个类装入时都要执行hook程序 不要求 高,要求对 class 文件结构和 Java 字节码有深刻了解
JDK Proxy 只能改写 method 反射引入性能代价 要求 低
ASM 几乎能完全控制类 无明显性能代价 不要求 中,能操纵需要改写部分的 Java 字节码

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值