我使用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()?
任何人都可以帮助我吗?
谢谢!
答案 0 :(得分:2)
这是一个经典的Spring AOP问题,这里已多次询问过。您使用Spring AOP,一种基于代理的“AOP lite”方法。因此,只有在真正从类外部调用公共的非静态代理方法时,才会触发处理AOP的动态代理子类。内部方法调用不使用代理,而是直接转到原始对象的目标方法。您在测试中看到的行为是可以预期的。
这个事实也在Spring AOP manual, chapter "Understanding AOP proxies"中解释(在那里寻找术语“自我调用”)。它还描述了AspectJ没有这种自我调用问题,因为AspectJ不是基于代理的,而是一个成熟的AOP框架。