快速业务通道

体验Java 1.5中面向方面(AOP)编程 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-23
作的BCEL 5.1版本有一个问题--它不支持分析注解。我可以载入正在重构的类并使用反射(reflection)查看注解。但是,如果这样,我就不得不使用RetentionPolicy.RUNTIME来代替RetentionPolicy.CLASS。我还必须在这些类中执行一些静态的初始化,而这些操作可能载入本地类库或引入其它的依赖关系。幸运的是,BCEL提供了一种插件(plugin)机制,它允许客户端分析字节码属性。我编写了自己的AttributeReader的实现(implementation),在出现注解的时候,它知道如何分析插入字节码中的RuntimeVisibleAnnotations和RuntimeInvisibleAnnotations属性。BCEL未来的版本应该会包含这种功能而不是作为插件提供。

编译时刻的字节码重构方法显示在示例代码的code/02_compiletime目录中。

但是这种方法有很多缺陷。首先,我必须给建立过程增加额外的步骤。我不能基于命令行设置或其它编译时没有提供的信息来决定打开或关闭重构操作。如果重构的或没有重构的代码需要同时在产品环境中运行,那么就必须建立两个单独的.jars文件,而且还必须决定使用哪一个。

体验Java 1.5中面向方面(AOP)编程(4)

时间:2010-12-05

在类载入时重构字节码

更好的方法可能是延迟字节码重构操作,直到字节码被载入的时候才进行重构。使用这种方法的时候,重构的字节码不用保存起来。我们的应用程序启动时刻的性能可能会受到影响,但是你却可以基于自己的系统属性或运行时配置数据来控制进行什么操作。

Java 1.5之前,我们使用定制的类载入程序可能实现这种类文件维护操作。但是Java 1.5中新增加的java.lang.instrument程序包提供了少数附加的工具。特别地,它定义了ClassFileTransformer的概念,在标准的载入过程中我们可以使用它来重构一个类。

为了在适当的时候(在载入任何类之前)注册ClassFileTransformer,我需要定义一个premain方法。Java在载入主类(main class)之前将调用这个方法,并且它传递进来对Instrumentation对象的引用。我还必须给命令行增加-javaagent参数选项,告诉Java我们的premain方法的信息。这个参数选项把我们的agent class(代理类,它包含了premain方法)的全名和任意字符串作为参数。在例子中我们把Instrumentor类的全名作为参数(它必须在同一行之中):

-javaagent:boxpeeking.instrument.InstrumentorAdaptor= boxpeeking.status.instrument.StatusInstrumentor

现在我已经安排了一个回调(callback),它在载入任何含有注解的类之前都会发生,并且我拥有Instrumentation对象的引用,可以注册我们的ClassFileTransformer了:

public static void premain (String className, Instrumentation i) throws ClassNotFoundException, InstantiationException, IllegalAccessException {   Class instClass = Class.forName(className);   Instrumentor inst = (Instrumentor)instClass.newInstance();   i.addTransformer(new InstrumentorAdaptor(inst)); }

我们在此处注册的适配器将充当上面给出的Instrumentor接口和Java的ClassFileTransformer接口之间的桥梁。

public class InstrumentorAdaptor implements ClassFileTransformer {   public byte[] transform (ClassLoader cl,String className,Class classBeingRedefined, ProtectionDomain protectionDomain,byte[] classfileBuffer)   {    try {     ClassParser cp =new ClassParser(new ByteArrayInputStream(classfileBuffer),className + ".java");     JavaClass jc = cp.parse();     ClassGen cg = new ClassGen(jc);     for (Annotation an : getAnnotations(jc.getAttributes())) {      instrumentor.instrumentC

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号