【发布时间】:2016-09-26 14:13:54
【问题描述】:
在将此问题标记为重复之前,请通读,因为 我已经浏览了一些关于 SO 和其他地方的帖子,但是 仍然未能找到解决我的问题的方法。
我正在尝试在 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 config条目如下:
<aop:aspectj-autoproxy />
<bean id="logAspect" class="somep2.LoggingAspect" />
在运行 mvn clean install 时,构建成功,并且存在以下日志条目 w.r.t 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 上
我尝试了很多方法,但都没有奏效。请让我知道我缺少什么。
感谢任何帮助。
【问题讨论】:
-
你在你的bean配置类中添加
@EnableAspectJAutoProxy注解了吗? -
我对 spring 和 aspectj 都很陌生,所以如果我错了,请纠正我。鉴于我已经有一个 spring 配置文件,其中设置了方面自动代理并且我正在那里定义我的 bean,这是否有必要?
-
在
process-sources阶段调用aspectj 插件对我来说很奇怪,因为它在正常编译阶段之前。默认的maven-compiler-plugin在你的构建中甚至被禁用了吗?我不确定如果它没有被禁用会发生什么,因为那样你会同时运行 aspectj 编译器和普通的 java 编译器,java 编译器在调用 aspectj 编译器的阶段之后被调用,可能会覆盖由 aspectj 编译创建的编译类。更改您的构建,以便在正确的阶段仅使用 aspectj 编译器:compile。 -
@NándorElődFekete 不,我的
maven-compiler-plugin没有被禁用。我尝试将我的ajc 的phase更改为compile,但它不起作用。我仍然收到建议加入点的消息。我想知道这是否与我正在使用在这个项目中创建的战争在另一个项目中建立一个耳朵的事实有关,然后我正在部署该项目。让我知道你的想法。 -
尝试完全禁用
maven-compiler-plugin并将aspectj 编译器附加到compile阶段。
标签: spring spring-aop aspectj-maven-plugin