首先,这个问题本质原因和我之前写的这篇文章《Spring事务调用类自己方法失效解决办法和原因》是一样的,都是动态代理失效导致的。
最近在开发中遇到了一个关于Spring AOP的问题。需求是统计某个方法的调用次数,我尝试使用Spring AOP来实现,但发现当方法被内部调用时,增强逻辑不生效。以下是详细描述和解决方案。
问题描述
我定义了一个接口ISon
,包含方法A
和方法B
。在接口实现类Son
中,方法B
调用了方法A
。同时,我通过AOP切面对方法A
进行了增强。测试发现,当直接调用A
时,增强逻辑正常工作;但当通过方法B
调用A
时,增强逻辑失效。
失效原因
原因在于,方法A
被调用是基于AOP生成的代理对象进行的调用;而方法B
调用方法A
时,是直接通过this
目标对象调用,并不是通过代理对象。
解决方案
为了解决这个问题,我需要确保即使是内部调用也能触发增强逻辑。一种方法是使用AopContext.currentProxy()
来获取代理对象,并调用其方法。同时,需要在应用配置中开启AOP支持,并暴露代理对象。
-
开启AOP支持:在应用配置中添加以下注解:
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
-
修改方法调用:在方法
B
中,不直接调用A
,而是通过代理对象调用:@Override public void B() { System.out.println("method B"); ((Son) AopContext.currentProxy()).A(); }
-
获取上下文的Bean再调用:另一种方法是通过应用上下文获取Bean,然后调用其方法:
@Autowired private ApplicationContext applicationContext; ((Son) applicationContext.getBean(Son.class)).A();
通过这些修改,无论是直接调用还是内部调用,方法A
的增强逻辑都能正常工作。这样,我就可以准确统计方法的调用次数了。