Java 编程的动态性,第 6 部分: 利用 Javassist 进行面向方面的更改
2010-03-18 00:00:00 来源:WEB开发网 public static void reportSet(Object target, String value) {
System.out.println("Call to set value " + value);
}
编译没有问题,但是当我运行它时它就会中断:
[dennis]$ java -cp .:javassist.jar TranslateConvert Bean setA BeanTest
Bean values are A and B
java.lang.NoSuchMethodError: TranslateConvert.reportSet(LBean;Ljava/lang/String;)V
at BeanTest.changeValues(BeanTest.java:17)
at BeanTest.main(BeanTest.java:23)
at ...
有办法绕过这种限制。一种解决方案是在运行时实际生成与目标方法相匹配的自定义监视方法。不过这要做很多工作,在本文中我不打算试验这种方法。幸运的是,Javassist 还提供了另一种处理系统字节码转换的方法。这种方法使用 javassist.ExprEditor ,与 CodeConverter 相比,它更灵活、也更强大。
容易的类剖析
用 CodeConverter 进行字节码转换与用 javassist.ExprEditor 的原理一样。不过, ExprEditor 方式也许更难理解一些,所以我首先展示基本原理,然后再加入实际的转换。
清单 3 显示了如何用 ExprEditor 来报告面向方面的转换的可能目标的基本项目。这里我在自己的 VerboseEditor 中派生了 ExprEditor 子类,重写了三个基本的类方法 ―― 它们的名字都是 edit() ,但是有不同的参数类型。如 清单 1 中的代码,我实际上是在 DissectionTranslator 内部类的 onWrite() 方法中使用这个子类,对从 ClassPool 实例中加载的每一个类,在对类对象的 instrument() 方法的调用中传递一个实例。
更多精彩
赞助商链接