Spring aop没有在一个方法上触发但在另一个方法上触发

时间:2016-11-09 04:08:18

标签: spring aop spring-aop

我使用AOP将监视器与业务逻辑分开。但是当我使用junit来测试我的aop代码时,我发现在执行方法B时不会触发AOP,但是在执行方法A时会触发AOP。方法B调用方法A.

我的伪代码如下:

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

我的主要逻辑如下:

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

然后当我用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;
    }
}

为什么我在MainClass中测试方法B时不会触发 monitorA()

任何人都可以帮助我吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

这是一个经典的Spring AOP问题,这里已多次询问过。您使用Spring AOP,一种基于代理的“AOP lite”方法。因此,只有在真正从类外部调用公共的非静态代理方法时,才会触发处理AOP的动态代理子类。内部方法调用不使用代理,而是直接转到原始对象的目标方法。您在测试中看到的行为是可以预期的。

这个事实也在Spring AOP manual, chapter "Understanding AOP proxies"中解释(在那里寻找术语“自我调用”)。它还描述了AspectJ没有这种自我调用问题,因为AspectJ不是基于代理的,而是一个成熟的AOP框架。