Spring中使用它所集成的AspectJ有两种方式:
- 直接完全用AspectJ
这种已经脱离了Spring,跟它没一分钱关系了。自己定义AspectJ语法的.aj文件
- 使用@Aspect annotation
使用,这种更加简单
两种方式如何选择?
- 当AspectJ在你的设计中占据很大的角色时,并且你又刚好是用Eclipse来做开发,那么用AspectJ Development Tools (AJDT)Eclipse插件来使用AspectJ语法来定义是最佳选择:它更整洁和简单,因为AspectJ就是为了写切面而开发的语言。
- 如果你不是用Eclipse,或者只有少量的切面,在你的应用中并不占主要角色,你就可以选择用annotation,然后在build脚本中加入Aspect的Weaving部分。
这两种,都会在真正加载时加载Weaving后的class。
它怎么做到的呢?我们看看过实现一个织入过程。
AspectJ支持两种Weaving:CTW(CompileTimeWeaving)或LTW(LoadTimeWeaving)。
CTW
在编译时引入AspectJ的编译器,最终的字节码是已经Weaving后的代码。
- 写aspect的.aj文件(AspectJ的语言)或者写aspect的 JAVA类带上 @Aspect
- 写maven或ant脚本,引入AspectJ的编译器进行编译
LTW
在加载时引入AspectJ的类加载器,在类加载到JVM时,织入切面。
- 写aspect的.aj文件(AspectJ的语言)或者写aspect的 JAVA类带上 @Aspect
- 写一个META-INF/aop.xml,指明aspect
- 修改应用启动参数,通过设定JVM的-javaagent参数引入LTW的织入器类包,以代替JVM默认类加载器
举例
为方便起见,还是使用之前的Zoo的annotation代码,参见Spring AOP @Aspect support annotation一文
CTW很简单,只需要修改.pom即可
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<complianceLevel>1.6</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>RunnableTest</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.edi.poc.Zoo</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
为方便起见,我把这个包做了一个可执行jar,叫RunnableTest.jar。
运行mvn clean install后,在target目录找到它,运行如下:
java -jar RunnableTest.jar
Dinosaur hall is opened.
The People Zoo is opened.
Before method...
Charge Jack $1.00 for ticket.
Jack needs to be charged first.
Dianosaur hall charges Jack $2.00
Jack visited diano hall.
After return...
Dinosaur hall is closed.
The People Zoo is closed.
可以看到完全跟上篇文章中输出一样。
用jad反编译看看包里的Zoo.class
public Hall enter(Entrant ???, HALL_NAME arg2)
{
Object localObject2 = ???;
Object localObject1;
Object localObject3 = localObject1; JoinPoint localJoinPoint = Factory.makeJP(ajc$tjp_0, ???, ???, localObject2, localObject3);
HALL_NAME hallName;
Entrant e;
MyAspect.aspectOf().before(localJoinPoint); charge(e);
return (Hall)this.halls.get(hallName);
}
这里的enter方法已然已被Weaving了。
LTW的例子
我们在src/main/resources/下创建 META-INF/aop.xml
<aspectj>
<aspects>
<aspect name="com.edi.poc.aop.MyAspect"/>
</aspects>
</aspectj>
启动时加入-javaagent:<path>/aspectjweaver-1.6.12.jar即可得到同样结果
参考文章:
http://opoo.org/aspectj-compile-time-weaving/
http://www.andrewewhite.net/wordpress/2010/03/17/aspectj-annotation-tutorial/
http://log-cd.iteye.com/blog/562056
本文源码:
https://github.com/EdisonXu/POC/tree/master/intro-aop
Spring + AspectJ
最新推荐文章于 2024-04-12 15:24:52 发布