标签:AspectJ编绎期织入
Aspectj是Eclipse基金会下的子项目,AspectJ提供了两种方式实现切面代码织入编绎期织入:分为三种情况
编绎class文件时织入
编绎后织入
类加载时织入
运行时织入
本文是在使用编绎class文件织入实践介绍
aspectJ提供了两种切面的实现方式
基于.aj文件描述
基于java注解
以下介绍是基于java注解
在单模块项目中使用AspectJ的编绎期织入特性时,只需要在pom文件加入aspectj依赖和aspectj编绎插件即可:
<properties>
<aspectj.version>1.8.9</aspectj.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
<XaddSerialVersionUID>true</XaddSerialVersionUID>
<showWeaveInfo>true</showWeaveInfo>
</configuration>
<executions>
<execution>
<id>compile_with_aspectj</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile_with_aspectj</id>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>重新编绎项目,在生成的class文件里可以找到ajc生成的类
如果在多模块项目,在具体的某个子模块声明切面类,定义切点表达式,但是连接点切分散在各个其他模块时,ajc扫描具到切点表达式时,只会在本模块扫描对应的连接点,其他模块的连接点是没有办法编绎期切入切面,ajc是不会在编绎其他模块时再去扫描有没有某个切点表达式与当前连接点匹配的。为了解决这个问题,需要把ajc插件定义在parent pom文件里
<properties>
<aspectj.version>1.8.9</aspectj.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
dependency>
<groupId>com.xx.xx</groupId>
<artifactId>xx_Aspectj</artifactId>
<version>T.0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
<XaddSerialVersionUID>true</XaddSerialVersionUID>
<showWeaveInfo>true</showWeaveInfo>
<aspectLibraries>
<aspectLibrary>
<groupId>com.aiatss.coast</groupId>
<artifactId>xx_Aspectj</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<id>compile_with_aspectj</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile_with_aspectj</id>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.xx.xx</groupId>
<artifactId>xx_Aspectj</artifactId>
<version>T.0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>像上面的配置,如果子模块project_Aspectj也是作为子模块引用了parent pom文件,这时编绎时会报错:
The projects in the reactor contain a cyclic reference: Edge between 'Vertex{label='com.xx.xx:xx_Aspectj:T.0.0.1-SNAPSHOT'}'
and 'Vertex{label='com.xx.xx:Framework:T.0.0.1-SNAPSHOT'}' introduces to cycle in the graph
com.xx.xx:Framework:T.0.0.1-SNAPSHOT --> com.xx.xx:xx_Parent:T.0.0.1-SNAPSHOT --> com.xx.xx:xx_Aspectj:T.0.0.1-SNAPSHOT --> com.xx.xx:Framework:T.0.0.1-SNAPSHOT -> [Help 1]这是一个cyclic reference问题,即是:xx_aspectj模块引用了parent pom项目,同时parent pom项目也引用了xx_aspectj项目,maven认为这是个错误,不应该出现,使用以下方式改造
首先把aspectj插件里的dependencies去掉,如下:
<properties>
<aspectj.version>1.8.9</aspectj.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
dependency>
<groupId>com.xx.xx</groupId>
<artifactId>xx_Aspectj</artifactId>
<version>T.0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
<XaddSerialVersionUID>true</XaddSerialVersionUID>
<showWeaveInfo>true</showWeaveInfo>
<aspectLibraries>
<aspectLibrary>
<groupId>com.aiatss.coast</groupId>
<artifactId>xx_Aspectj</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<id>compile_with_aspectj</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile_with_aspectj</id>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>然后在xx_AspectJ子项目里屏蔽parent pom的插件,如下:
<plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.10</version> <configuration> <source>1.8</source> <target>1.8</target> <complianceLevel>1.8</complianceLevel> <XaddSerialVersionUID>true</XaddSerialVersionUID> <showWeaveInfo>true</showWeaveInfo> </configuration> <executions> <execution> <id>compile_with_aspectj</id> <phase>none</phase> </execution> <execution> <id>test-compile_with_aspectj</id> <phase>none</phase> </execution> </executions> </plugin> </plugins>
这是,如果xx_AspectJ项目要引用其他公共子模块时(比例:xx_common 、xx_repository)项目时,怎样么办?只能在xx_common、xx_repository项目中禁用来自parent pom AspectJ插件了,如此xx_AspectJ模块里的切面就无法切入xx_common、xx_repository项目的连接点了
在实践时参考文章:http://www.mojohaus.org/aspectj-maven-plugin/multimodule/multimodule_strategy.html
多模块maven项目使用Eclipse的 AspectJ编绎期织入
标签:AspectJ编绎期织入
原文地址:http://blog.51cto.com/5914679/2096848