Before marking this question as a duplicate, please read through, as I've gone through a number of posts on SO and other places but have still failed to find a solution to my problem.
我正在尝试在 Spring + AspectJ 中实现一个项目,正如标题所示,我可以看到aspectj maven 插件应用了建议,但实际上并没有调用它。
我正在尝试应用基于注释的建议。 以下是注释类:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface LogThis {
String name();
int id();
int eventID();
}
此注释已应用于通过 ajax 调用从前端 js 脚本调用的方法。调用的方法如下:
@RequestMapping(value = "/handle", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.NO_CONTENT)
@LogThis(name = "name", ID = 12345, eventID = 12345)
public void create(@RequestBody TodoDTO todo, HttpServletRequest req) {
//perform some action
}
该建议应用于 LogThis
注释,建议如下:
@Pointcut("@annotation(LogThis)")
public void genericPointcut() {
}
@Pointcut("execution(* *(..))")
public void atExecution() {
}
@Async
@Before("genericPointcut() && atExecution()")
public void logBefore(JoinPoint joinPoint) throws NoSuchMethodException, SecurityException {
// Perform logging
}
注释类和方面位于同一个包中,而被建议的类位于不同的包中,但所有内容都在同一个项目中。
我已按如下方式配置我的 maven pom.xml 文件(仅显示相关部分):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>${java.source-target.version}</source>
<target>${java.source-target.version}</target>
<Xlint>ignore</Xlint>
<complianceLevel>${java.source-target.version}</complianceLevel>
<encoding>${project.build.sourceEncoding}</encoding>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
属性是:
<properties>
<sonar.language>java</sonar.language>
<java.source-target.version>1.7</java.source-target.version>
<aspectj.version>1.8.7</aspectj.version>
</properties>
aspectj 依赖项是:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
正在使用的Spring版本是4.1.3.RELEASE
。
我的方面的 spring 配置条目如下:
<aop:aspectj-autoproxy />
<bean id="logAspect" class="somep2.LoggingAspect" />
运行mvn clean install
时,构建成功,并且以下日志条目存在于aspectj:
[INFO] --- aspectj-maven-plugin:1.8:compile (default) @ myproj ---
[INFO] Showing AJC message detail for messages of types: [error, warning, fail]
[INFO] Join point 'method-execution(void somep.SomeC.create(param1, param2))' in Type 'somep.SomeC' (SomeC.java:63) advised by before advice from 'somep2.LoggingAspect' (LoggingAspect.java:36)
[INFO]
[INFO] --- aspectj-maven-plugin:1.8:test-compile (default) @ myproj ---
[WARNING] No sources found skipping aspectJ compile
根据日志,已找到并建议连接点,但在调用 create()
方法时从未调用 logBefore()
方法。我确信这一点,因为我正在使用 FileWriter
写入文件,但没有写入任何内容。
部署详细信息: 该项目是作为另一个项目的一部分构建的,该项目创建一个ear文件,然后将其部署在JBoss 6.3上
我尝试了多种方法,但没有任何效果。请让我知道我缺少什么。
感谢任何帮助。
最佳答案
我终于让它工作了。事实证明我把事情搞得太复杂了。不需要aspectj编译器。我所要做的就是告诉 spring 我的方面也是一个组件,以便它可以注入(inject)我的建议。
以下是完整的更改列表:
- 从pom.xml 中删除了aspectj-maven-plugin。这不是必需的。
- 删除了aspectj-tools和spring-aop依赖项,并将aspectj-weaver依赖项添加到pom.xml
- 从 spring 配置中删除了我的方面的 bean 条目。
- 使用
@Component
注释我的方面类,并确保它作为 Spring 组件扫描的一部分进行扫描。
希望这对其他人也有帮助。
PS。我仍然不完全明白为什么会这样,所以如果有人有解释,请评论。关于spring - 建议使用spectj Maven 连接点,但未调用建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39705236/