Spring aop not triggered on one method but trigger

2019-09-15 11:52发布

问题:

I use AOP to separate monitor from the bussiness logic. But when I use junit to test my aop code I found that AOP are not triggered when method B is executed but are triggered when method A is executed. And method B calls method A.

my pseudocode likes below :

@Aspect
public class TimeMonitor {
    @Pointcut("execution( * MainClass.A(..))")
    public void pointA();
    @Around("pointA()")
    Object monitorA(ProceedingJoinPoint jp ){
        try{
            jp.proceed();
        }catch(Exception e){
            logger.error("failed to execute A in TimeMonitor");
        }
    }

my main logic like below:

public class MainClass{
    public String A(){
    }
    public String B(){
        try{
            A();//call method A
        }catch(Exception e ){
            logger.error("failed to execute A in Main class");
        }
    }
}

Then when I do unit test with Junit:

public TimeMonitorTest{
    @Test
    public void TestA(){
        //test code here
        A();
        //AOP method monitorA will be triggered;
    }
    @Test
    public void TestB(){
        B();
        //AOP method monitorA will not be triggered;
    }
}

So why monitorA() not be triggered when I test method B in MainClass?

Can anyone help me ?

Thanks!!

回答1:

This is a classic Spring AOP question and has been asked many times here. You use Spring AOP, a proxy-based "AOP lite" approach. Thus, dynamic proxy subclasses taking care of AOP are only triggered if public, non-static proxy methods are really called from outside the class. Internal method calls do not use the proxy but go directly to the target method of the original object. The behaviour you see in your test is to be expected.

This fact is also explained in the Spring AOP manual, chapter "Understanding AOP proxies" (look for the term "self-invocation" there). It also describes that AspectJ does not have this self-invocation issue because AspectJ is not proxy-based but a full-fledged AOP framework.