2

我得到了 Spring AOP AspectJ 的一个奇怪行为:不应该建议自我调用,但在我的应用程序中它确实如此。来自Spring 文档

但是,一旦调用最终到达目标对象,在这种情况下是 SimplePojo 引用,它可能对自身进行的任何方法调用,例如 this.bar() 或 this.foo(),都将针对这个参考,而不是代理。这具有重要意义。这意味着自调用不会导致与方法调用相关的建议有机会执行。

但在我的简单应用程序中,由:

一个测试方面

@Aspect
@Component
public class TestAspect {

    private static final Logger logger = LoggerFactory.getLogger(TestAspect.class);

    @Pointcut("execution(* org.mypackage.TestService.method(..))")
    public void participateAroundPointcut(){}

    @Around("participateAroundPointcut()")
    public void testAround(ProceedingJoinPoint joinPoint) throws Throwable{
        logger.debug("Pre-execution;");

        joinPoint.proceed();

        logger.debug("Post-execution");
    }

}

测试服务:

@Service
public class TestService {

    private static final Logger logger = LoggerFactory.getLogger(TestService.class);

    public void method(){
        logger.debug("Executing method();");
    }

    public void service(){
        logger.debug("Executing service();");
        this.method();
    }
}

和一个配置文件:

<context:component-scan base-package="org.mypackage" />
<aop:aspectj-autoproxy  proxy-target-class="true" />
<bean id="testAspect" class="org.mypackage.aop.aspects.TestAspect" factory-method="aspectOf"/>

我得到了自我调用的建议:

DEBUG: org.mypackage.TestService - Executing service();
DEBUG: org.mypackage.aop.aspects.TestAspect - Pre-execution;
DEBUG: org.mypackage.TestService - Executing method();
DEBUG: org.mypackage.aop.aspects.TestAspect - Post-execution

我不明白为什么会这样。

4

3 回答 3

1

问题很可能是 IDE - 如果您使用 Eclipse 并为您的项目启用了 AspectJ,AspectJ 插件将编织您的目标类。尝试在 IDE 之外运行您的测试(如果它是 maven 项目,您可以运行mvn clean test),然后您应该会看到预期的行为

于 2013-01-25T11:36:29.477 回答
1

您的配置使用AspectJ实现。

它配置有: <aop:aspectj-autoproxy />(官方文档)

proxy-target-class="true"只是说将使用 CGLIB 代理而不是 Java 动态代理。

我猜你想用 CGLIB 代理配置 Spring AOP。在这种情况下,配置字符串如下所示:

<aop:config proxy-target-class="true">
...
</aop:config>
于 2013-10-23T19:00:53.957 回答
0

但是,一旦调用最终到达目标对象,在这种情况下是 SimplePojo 引用,它可能对自身进行的任何方法调用,例如 this.bar() 或 this.foo(),都将针对这个参考,而不是代理。这具有重要意义。这意味着自调用不会导致与方法调用相关的建议有机会执行。

仅当您的 AOP 配置为在代理模式下工作(这是默认模式)时才适用,但您配置了aspectj,它处理来自类外部的调用和自调用。

于 2013-01-25T11:15:24.650 回答