0

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!!

ningyuwhut
  • 609
  • 12
  • 27
  • how exactly are you calling A(); in TestA – kuhajeyan Nov 09 '16 at 05:36
  • can you reformat your code and use lowercase starting letters for your methods? `A()` in java looks like a constructor instead of a method. Also how you call in your test class `A()`? Shouldn't you instantiate first the `MainClass` and then call `A()` from it? I doubt if your `TimeMonitorTest` compiles at all. – pleft Nov 09 '16 at 08:56

1 Answers1

2

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.

kriegaex
  • 63,017
  • 15
  • 111
  • 202