Java编程的动态性,第6部分: 利用Javassist进行面向方面的更改 - 编程入门网
Java编程的动态性,第6部分: 利用Javassist进行面向方面的更改时间:2011-04-09 IBM Dennis M. SosnoskiJava 顾问 Dennis Sosnoski 在他的关于 Javassist 框架的三期文章中将精华部分留在 了最后。这次他展现了 Javassist 对搜索-替换的支持是如何使对 Java 字节码的编辑变得 像文本编辑器的“替换所有(Replace All )”命令一样容易的。想报告所有写入特定字段 的内容或者对方法调用中参数的更改中的补丁吗?Javassist 使这变得很容易,Dennis 向您 展示了其做法。 本系列的 第 4 部分和 第 5 部分讨论了如何用 Javassist 对二进制类进行局部更改。 这次您将学习以一种更强大的方式使用该框架,从而充分利用 Javassist 对在字节码中查找 所有特定方法或者字段的支持。对于 Javassist 功能而言,这个功能至少与它以类似源代码 的方式指定字节码的能力同样重要。对选择替换操作的支持也有助于使 Javasssist 成为一 个在标准 Java 代码中增加面向方面的编程功能的绝好工具。 第 5 部分介绍了 Javassist 是如何让您拦截类加载过程的 ―― 甚至在二进制类表示正 在被加载的时候对它们进行更改。这篇文章中讨论的系统字节码转换可以用于静态类文件转 换,也可以用于运行时拦截,但是在运行时使用尤其有用。 处理字节码修改 Javassist 提供了两种不同的系统字节码修改的处理方法。第一种技术是使用 javassist.CodeConverter 类,使用起来要稍微简单一些,但是可以完成的任务有很多限制 。第二种技术使用 javassist.ExprEditor 类的自定义子类,它稍微复杂一些,但是所增加 的灵活性足以抵销所付出的努力。在本文中我将分析这两种方法的例子。 代码转换 系统字节码修改的第一种 Javassist 技术使用 javassist.CodeConverter 类。要利用这 种技术,只需要创建 CodeConverter 类的一个实例并用一个或者多个转换操作配置它。每一 个转换都是用识别转换类型的方法调用来配置的。转换类型可分为三类:方法调用转换、字 段访问转换和新对象转换。 清单 1 给出了使用方法调用转换的一个例子。在这个例子中,转换只是增加了一个方法 正在被调用的通知。在代码中,首先得到将要使用的 javassist.ClassPool 实例,将它配置 为与一个翻译器一同工作 (正如在前面 第 5 部分 所看到的)。然后,通过 ClassPool 访 问两个方法定义。第一个方法定义针对的是要监视的“set”类型的方法(类和方法名来自命 令行参数),第二个方法定义针对的是 reportSet() 方法 ,它位于TranslateConvert 类中 ,并会报告对第一个方法的调用。 有了方法信息后,就可以用 CodeConverterinsertBeforeMethod() 配置一个转换,以在 每次调用这个 set 方法之前增加一个对报告方法的调用。然后所要做的就是将这个转换器应 用到一个或者多个类上。在清单 1 的代码中,我是通过调用类对象的 instrument() 方法, 在 ConverterTranslator 内部类的 onWrite() 方法中完成这项工作的。这将自动对从 ClassPool 实例中加载的每一个类应用这个转换。 清单 1. 使用 CodeConverter
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |