Spring + AspectJ

来源:互联网 发布:无圣光软件下载 编辑:程序博客网 时间:2024/04/30 13:56

    Spring中使用它所集成的AspectJ有两种方式:

    1. 直接完全用AspectJ

    这种已经脱离了Spring,跟它没一分钱关系了。自己定义AspectJ语法的.aj文件

     

    1. 使用@Aspect annotation

    使用,这种更加简单

     

    两种方式如何选择?

     

    1. AspectJ在你的设计中占据很大的角色时,并且你又刚好是用Eclipse来做开发,那么用AspectJ Development Tools AJDTEclipse插件来使用AspectJ语法来定义是最佳选择:它更整洁和简单,因为AspectJ就是为了写切面而开发的语言。
    2. 如果你不是用Eclipse,或者只有少量的切面,在你的应用中并不占主要角色,你就可以选择用annotation,然后在build脚本中加入AspectWeaving部分。

     

    这两种,都会在真正加载时加载Weaving后的class

    它怎么做到的呢?我们看看过实现一个织入过程。

    AspectJ支持两种WeavingCTW(CompileTimeWeaving)LTW(LoadTimeWeaving)

     

    CTW

    在编译时引入AspectJ的编译器,最终的字节码是已经Weaving后的代码。

    1. aspect.aj文件(AspectJ的语言)或者aspect JAVA类带上 @Aspect
    2. mavenant脚本,引入AspectJ的编译器进行编译

     

    LTW

    在加载时引入AspectJ的类加载器,在类加载到JVM时,织入切面。

    1. aspect.aj文件(AspectJ的语言)或者aspect JAVA类带上 @Aspect
    2. 写一个META-INF/aop.xml,指明aspect
    3. 修改应用启动参数,通过设定JVM-javaagent参数引入LTW的织入器类包,以代替JVM默认类加载器

     

    举例

    为方便起见,还是使用之前的Zooannotation代码,参见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

     

原创粉丝点击