WEB开发网
开发学院软件开发Java Java 编程的动态性,第 6 部分: 利用 Javassist 进... 阅读

Java 编程的动态性,第 6 部分: 利用 Javassist 进行面向方面的更改

 2010-03-18 00:00:00 来源:WEB开发网   
核心提示: 如果直接运行清单 2 中的 中的 BeanTest 程序,则输出如下: [dennis]$java-cp.BeanTestBeanvaluesareoriginalAandoriginalBBeanvaluesarenewAandnewB如果用 清单 1 中的 TranslateConvert

如果直接运行清单 2 中的 中的 BeanTest 程序,则输出如下:

[dennis]$ java -cp . BeanTest 
Bean values are originalA and originalB 
Bean values are newA and newB 

如果用 清单 1 中的 TranslateConvert 程序运行它并指定监视其中的一个 set 方法,那么输出将如下所示:

[dennis]$ java -cp .:javassist.jar TranslateConvert Bean setA BeanTest 
Bean values are originalA and originalB 
Call to set value newA 
Bean values are newA and newB 

每项工作都与以前一样,但是现在在执行这个程序时,所选的方法被调用时会有一个通知。

在这个例子中,可以用其他的方法容易地实现同样的效果,例如通过使用 第 4 部分 中的技术在实际的 set 方法体中增加代码。这里的区别是,在使用位置增加代码让我有了灵活性。例如,可以容易地修改 TranslateConvert.ConverterTranslatoronWrite() 方法来检查正在加载的类名,并只转换在我想要监视的类的清单中列出的类。直接在 set 方法体中添加代码无法进行这种有选择的监视。

系统字节码转换由于提供了灵活性而使其成为为标准 Java 代码实现面向方面的扩展的强大工具。在本文后面您会看到更多这方面的内容。

转换限制

由 CodeConverter 处理的转换很有用,但是有局限性。例如,如果希望在调用目标方法之前或者之后调用一个监视方法,那么这个监视方法必须定义为 static void 并且必须先接受一个目标方法的类的参数,然后是与目标方法所要求的同样数量和类型的参数。

这种严格的结构意味着监视方法需要与目标类和方法完全匹配。举一个例子,假设我改变了 清单 1 中 reportSet() 方法的定义,让它接受一个一般性的 java.lang.Object 参数,想使它可以用于不同的目标类:

上一页  1 2 3 4 5 6 7 8 9  下一页

Tags:Java 编程 动态性

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接