Self-invocation shouldn't be adviced but it does

与世无争的帅哥 提交于 2019-12-22 15:02:55

问题


I'm getting a weird behavior by Spring AOP AspectJ: self-invocation shouldn't be adviced, but in my application it does. From Spring documentation:

However, once the call has finally reached the target object, the SimplePojo reference in this case, any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy. This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute.

But in my simple application, composed by:

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

}

a 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();
    }
}

and a configuration file:

<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"/>

I get the self-invocation adviced:

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

I can't figure out why this happens.


回答1:


The issue is most likely the IDE - if you are using Eclipse with AspectJ enabled for your project, the AspectJ plugin will weave your target classes. Try to run your test outside of the IDE (if it is maven project, you can run mvn clean test) and you should then see the expected behavior




回答2:


Your configuration uses AspectJ implementation.

It is configured with: <aop:aspectj-autoproxy />. (official documentation)

proxy-target-class="true" only says that CGLIB proxies will be used instead of Java Dynamic Proxies.

I guess you want to configure Spring AOP with CGLIB proxies. In that case the config string looks like:

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



回答3:


However, once the call has finally reached the target object, the SimplePojo reference in this case, any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy. This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute.

This is only true if your AOP is configured to work in proxy mode (which is default), but you configured aspectj, which handles both calls from outside the class, and self-invocations.



来源:https://stackoverflow.com/questions/14520091/self-invocation-shouldnt-be-adviced-but-it-does

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!