平时使用aspect开发程序时,一般都是使用普通的aspect语法,然后通过使用ajc进行编译之后,再在命令行下面运行。这样,对于使用ide工具进行java程序开发的人员来说非常麻烦。自aspectj支持java5语法之后,就不再直接使用普通的aspect语法了,而是直接使用Aspectj Annotation语法,然后通过ltw来直接运行aspectj程序。
本文主要讲解如何使用aspectj的ltw功能进行程序开发,以及对于其中一个在javac环境下的特殊配置文件处理。
之所以使用ltw,是因为这样不需要在进行程序开发时照顾特殊的aspect语法,而且相应的编辑器也不会因为不能识别aspect语法而报错了。而且在进行编译时,也不需要使用特殊的ajc进行程序编译(一般使用ajc会消费大量内存,而且很可能会内存崩溃)。在进行运行时,直接运行相应的运行程序即可,而且对于设置的特殊java agent,也不需要时刻的修改(对于,非aspect程序,加上这一个agent也不会有错误发生)。
下面开始,简单写一个注解版的aspect,如下所示:
/** 匹配所有transaction注释的公共静态方法 */ @Pointcut( "execution(@org.springframework.transaction.annotation.Transactional static * *.*(..))") private void executionOfStaticTransactionalMethod() { }
以上就是一个普通的point声明,现在开始使用这个point,如下所示:
@After("executionOfStaticTransactionalMethod()") public void after() { cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo()); }
以上就是使用先前声明的point,通过追加一个after的断点操作。表示在该断点程序执行完毕之后,还需要做什么逻辑。这里只需要引用声明断点的那个方法名即可。写好程序之后,在ide中的java执行变量中,只需要加上以下的参数,即可以直接运行了。
-javaagent:E:\java\aspectj\lib\aspectjweaver.jar
这样,即可通过向java虚拟机添加一个特殊的instrument来运行load time weaver了。
在这种情况下,我们的程序是事先通过使用普通的javac进行编译的,然后在运行阶段,再由aspectj解析相应的aspect再对其他的类进行weaver的。这种情况下,我们一般需要写一个aop.xml文件,该文件放在META-INF目录下,用于声明用到的aspect以及哪些类需要进行编织。
<?xml version="1.0" encoding="UTF-8" ?> <aspectj> <weaver options="-Xset:weaveJavaxPackages=true -Xlint:ignore -verbose"> <!-- only weave classes in this package --> <include within="com.flydmeng..*"/> <exclude within="*..*CGLIB*" /> <exclude within="*..*JAVAASSIST*" /> </weaver> <aspects> <aspect name="com.flydmeng.DomainTransactionAspect"/> </aspects> </aspectj>
aspectj在运行时(即通过添加一个java agent的方式进行声明)会寻找所有的aop.xml文件,并加载相应的设置。一般情况下,使用了上面的开发方式,一般的aspectj程序就可以运行。
这里面有一个需要特别注意的地方:对于使用javac编译的程序在使用aspectj时,相应的aspectj必须进行weaver,否则相应的编织不会成功。
参考资料:http://aspectj.2085585.n4.nabble.com/How-to-debug-aspectjweaver-for-LTW-td2084056.html
http://aspectj.2085585.n4.nabble.com/LTW-requirements-for-annotation-style-Aspect-s-compiled-with-javac-td3042139.html
原因可以参照以上两篇文章,原因在于普通的java程序在经过javac编译之后,但它并不是一个有效的aspectj文件,需要被aspectj再次编译成有效的aspect(比如需要追加aspectOF方法等),如果没有经过再次weaver,相应的aspect在运行时就始终是经过javac编译的样子,运行时代码中并没有aspectJ需要使用的aspectOf方法!这样,尽管在aop.xml中声明它是一个aspect,但最终使用时,这个aspectj却总不会有效,就是因为它并不是一个有效的aspect(除非再次被weaver)。
所以在书写aop.xml时,除在aspects中声明了这个aspect之后,还要再次确认这个aspect在weaver中被声明。一般情况下,在weaver中使用include语法,即包括一个包下的所有类,这个包就包含了我们所声明的aspect。如上面的声明一样,具体的aspect(包名为com.flydmeng)也同样在weaver包(com.flydmeng.*)下,所以这个aspect会再次被weaver,就可以正确的运行。
在这种情况下,在使用spring的ltw时,我们都要配置aspect,在配置时,就要使用工厂方法来注入相应的属性(详情可以本站的一篇文章:http://www.iflym.com/index.php/code/the-theory-about-spring-and-aspectj-post.html)。在这种情况下,使用的工厂方法aspectOf在开发及编译期是不存在的,但在运行期,经过aspectj再次编织之后,这个方法就存在了,所以spring就可以成功的使用该类了。
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/use-java-develop-compile-annotated-aspectj-programe.html
你好,按照你的方式配置,但是不起作用。老是找不大aspectof方法,请指教
请参考文中的红色字体部分以及后面的解释。