per(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 类:
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 字节码 |
|