使用普通java开发编译注解版的aspectj程序

使用java5语法(annotation)版的aspectj进行ltw化的aspect开发。在进行运行配置时,必须保证相应的aspect也同样在weaver中,以进行再次编织。

     平时使用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

相关文章:

作者: flym

I am flym,the master of the site:)

《使用普通java开发编译注解版的aspectj程序》有2个想法

  1. 你好,按照你的方式配置,但是不起作用。老是找不大aspectof方法,请指教

发表评论

邮箱地址不会被公开。 必填项已用*标注