Search code examples
springspring-bootaopspring-aop

AfterReturning advice not executed


@Component
Class A {
 
    public String methodA() {
      return methodB();
    }
        
        
    @Publish
    public String methodB() {
      return "abc";
    }
}
@Component
@Aspect
public class PublishEvents {
    
    @AfterReturning(value = "@annotation(Publish)", returning = "retVal")
    public void sendEvent(JoinPoint joinPoint, Object retVal) {
        system.out.println("sending event");
    }
}

So I have an aspect class PublishEvents defined with AfterReturning Advice. This advice gets executed when I use @Publish which is a custom defined annotation, over methodA of class A but it does not get executed when I put it over methodB of class A. Note that methodB is called from methodA.

Can someone tell me what I am missing here?


Solution

  • Spring AOP is proxy-based, which means that an additional class for proxying bean calls is created by Spring, for more details about proxy mechanisms check the link.

    The key thing to understand is that calls on that component reference are calls on the proxy. To make it more clear, other beans, that autowire the A component, actually contain the proxied instance, not the component instance itself. As a result, the proxy can delegate to all the interceptors (advice) relevant to that particular method call.

    However, any method calls it may make on itself, such as methodA invoking methodB in your case, will be invoked against the instance itself, not the proxy. This has important implications. It means that self-invocation will not result in the AfterReturning advice getting a chance to run.

    Unlike Spring AOP, AspectJ has no issues with self-invocation since it's not a proxy-based AOP framework. Check Indra's answer for more details and examples.

    For reference: Understanding AOP Proxies