快速业务通道

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

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-23
en,MethodGen methodGen,Annotation a); }

ClassGen和MethodGen都是BCEL类,它们使用了Builder模式(pattern)。也就是说,它们为改变其它不可变的(immutable)对象、以及可变的和不可变的表现(representation)之间的转换提供了方法。

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

时间:2010-12-05

现在我需要为接口编写实现,它必须用恰当的StatusManager调用更换@Status注解。前面提到,我希望把这些调用包含在try-finally代码块中。请注意,要达到这个目标,我们所使用的注解必须用@Retention(RetentionPolicy.CLASS)进行标记,它指示Java编译器在编译过程中不要抛弃注解。由于在前面我把@Status声明为@Retention(RetentionPolicy.SOURCE)的,我必须更新它。

在这种情况下,重构字节码明显比重构源代码更复杂。其原因在于try-finally是一种仅仅存在于源代码中的概念。Java编译器把try-finally代码块转换为一系列的try-catch代码块,并在每一个返回之前插入对finally代码块的调用。因此,为了把try-finally代码块添加到已有的字节码中,我也必须执行类似的事务。

下面是表现一个普通方法调用的字节码,它被StatusManager更新环绕着:

0: ldc #2; //字符串消息 2: invokestatic #3; //方法StatusManager.push:(LString;)V 5: invokestatic #4; //方法 doSomething:()V 8: invokestatic #5; //方法 StatusManager.pop:()V 11: return

下面是相同的方法调用,但是位于try-finally代码块中,因此,如果它产生了异常会调用StatusManager.pop():

0: ldc #2; //字符串消息 2: invokestatic #3; //方法 StatusManager.push:(LString;)V 5: invokestatic #4; //方法 doSomething:()V 8: invokestatic #5; //方法 StatusManager.pop:()V 11: goto 20 14: astore_0 15: invokestatic #5; //方法 StatusManager.pop:()V 18: aload_0 19: athrow 20: return Exception table: from to target type 5 8 14 any 14 15 14 any

你可以发现,为了实现一个try-finally,我必须复制一些指令,并添加了几个跳转和异常表记录。幸运的是,BCEL的InstructionList类使这种工作相当简单。

在运行时重构字节码

现在我拥有了一个基于注解修改类的接口和该接口的具体实现了,下一步是编写调用它的实际框架组件。实际上我将编写少量的框架组件,先从运行时重构所有类的框架组件开始。由于这种操作会在build过程中发生,我决定为它定义一个Ant事务。build.xml文件中的重构目标的声明应该如下:

<instrument class="com.pkg.OurInstrumentor"> <fileset dir="$(classes.dir)"> <include name="**/*.class"/> </fileset> </instrument>

为了实现这种事务,我必须定义一个实现org.apache.tools.ant.Task接口的类。我们的事务的属性和子元素(sub-elements)都是通过set和add方法调用传递进来的。我们调用执行(execute)方法来实现事务所要执行的工作--在示例中,就是重构<fileset>中指定的类文件。

public class InstrumentTask extends Task {   ...   public void setClass (String className) { ... }   public void addFileSet (FileSet fileSet) { ... }   public void execute () throws BuildException {    Instrumentor inst = getInstrumentor();    try {     DirectoryScanner ds =fileSet.getDirectoryScanner(project);     // Java 1.5 的"for" 语法     for (String file : ds.getIncludedFiles()) {      instrumentFile(inst, file);     }    } catch (Exception ex) {     throw new BuildException(ex);    }   }   ... }

用于该项操

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号