【问题标题】:aspectj maven joinpoint advised but advice not calledaspectj maven joinpoint 建议但未调用建议
【发布时间】: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


【解决方案1】:

我终于让它工作了。原来我把事情复杂化了。不需要 aspectj 编译器。我所要做的就是告诉 spring 我的方面也是一个组件,以便它可以注入我的建议。

以下是完整的更改列表:

  1. 从 pom.xml 中删除了 aspectj-maven-plugin。这不是必需的。
  2. 删除了 aspectj-tools 和 spring-aop 依赖项,并将 aspectj-weaver 依赖项添加到 pom.xml 中
  3. 从 spring 配置中删除了我的方面的 bean 条目。
  4. @Component 注释了我的方面类,并确保它作为 Spring 组件扫描的一部分被扫描。

希望这对其他人也有帮助。

附言。我仍然不完全理解为什么会这样,所以如果有人有解释,请发表评论。

【讨论】:

  • 很奇怪。我有同样的问题。当我用 @Component 注释我的 Aspect 时,它突然被 Spring 拾取。不幸的是,我不知道更多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多