Java 编程的动态性,第 5 部分: 动态转换类
2010-03-18 00:00:00 来源:WEB开发网在此例中,唯一直接由 VerboseLoader 加载的类是 Run 类。 Run 使用的其他所有类都是核心 Java 类,它们是通过父 classloader 使用委托来加载的。这其中的大多数(如果不是全部的话)核心类实际上都会在 VerboseLoader 应用程序本身的启动期间加载,因此父 classloader 将只返回一个指向先前创建的 java.lang.Class 实例的引用。
Javassist 拦截
清单 2 中的 VerboseClassloader 展示了拦截类加载的基本过程。为了在加载时修改类,我们可以更进一步,向 findClass() 方法添加代码,把二进制类文件当作资源来访问,然后使用该二进制数据。Javassist 实际上包括了直接完成此类拦截的代码,因此与其进一步扩充这个例子,我们不如看看如何使用 Javassist 实现。
使用 Javassist 来拦截类加载的过程要依赖我们在 第 4 部分 中使用的相同 javassist.ClassPool 类。在该文中,我们通过名称直接从 ClassPool 请求类,以 javassist.CtClass 实例的形式取回该类的 Javassist 表示。然而,那并不是使用 ClassPool 的唯一方式――Javassist 还以 javassist.Loader 类的形式,提供一个使用 ClassPool 作为其类数据源的 classloader。
为了允许您在加载类时操作它们, ClassPool 使用了一个 Observer 模式。您可以向 ClassPool 的构造函数传递预期的观察者接口(observer interface)的一个实例 javassist.Translator 。每当从 ClassPool 请求一个新的类,它都调用观察者的 onWrite() 方法,这个方法能够在 ClassPool 交付类之前修改该类的表示。
javassist.Loader 类包括一个便利的 run() 方法,它加载目标类,并且使用所提供的参数数组来调用该类的 main() 方法(就像在 清单 1 中一样)。清单 4 展示了如何使用 Javassist 类和这个方法来加载和运行目标应用程序类。这个例子中简单的 javassist.Translator 观察者实现仅只是打印一条关于正在被请求的类的消息。
更多精彩
赞助商链接