不应该建议自我调用,但确实如此

时间:2013-01-25 10:39:36

标签: spring aspectj spring-aop aop

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

  

然而,一旦调用终于到达了目标对象,那么   在这种情况下,SimplePojo引用,它可能进行的任何方法调用   本身,例如this.bar()或this.foo(),将被调用   反对这个参考,而不是代理。这很重要   影响。 这意味着不会导致自我调用   与方法调用相关的建议有机会   执行

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

组成

一个TestAspect

@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");
    }

}

TestService:

@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

我无法弄清楚为什么会这样。

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您的配置使用AspectJ实施。

配置为: <aop:aspectj-autoproxy />(official documentation)

proxy-target-class="true"仅表示将使用CGLIB代理而不是Java Dynamic Proxies。

我想你想用CGLIB代理配置Spring AOP。在这种情况下,配置字符串看起来像:

<aop:config proxy-target-class="true">
...
</aop:config>

答案 2 :(得分:0)

  

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

仅当您的AOP配置为在代理模式下工作时(默认情况下),但您配置了 aspectj ,它处理来自类外部的调用和自我调用。< / p>