Spring AOP当方法被内部调用时,增强逻辑失效问题原因及解决方案
首先,这个问题本质原因和我之前写的这篇文章《Spring事务调用类自己方法失效解决办法和原因》是一样的,都是动态代理失效导致的。
最近在开发中遇到了一个关于Spring AOP的问题。需求是统计某个方法的调用次数,我尝试使用Spring AOP来实现,但发现当方法被内部调用时,增强逻辑不生效。以下是详细描述和解决方案。
问题描述
我定义了一个接口ISon
,包含方法A
和方法B
。在接口实现类Son
中,方法B
调用了方法A
。同时,我通过AOP切面对方法A
进行了增强。测试发现,当直接调用A
时,增强逻辑正常工作;但当通过方法B
调用A
时,增强逻辑失效。
public interface ISon {
void A();
void B();
}
@Service
public class Son implements ISon {
@Override
public void A() {
System.out.println("method A");
}
@Override
public void B() {
System.out.println("method B");
A();
}
}
@Aspect
@Component
public class AspectDemo {
@Pointcut(value = "execution(* com.example.transactiondemo.aop.ISon.A(..))")
public void pointCut(){
}
@Before("pointCut()")
public void before(JoinPoint joinPoint){
System.out.println("before ");
}
@After("pointCut()")
public void after(){
System.out.println("after ");
}
}
@Autowired
private ISon iSon;
@Test
public void test11(){
iSon.A();
System.out.println("-----------");
iSon.B();
}
before
method A
after
-----------
method B
method 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
的增强逻辑都能正常工作。这样,我就可以准确统计方法的调用次数了。
标签:
spring
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2023-07-17 Spring Boot中借助Redis实现分布式系统全局共享线程安全的阻塞队列
2018-07-17 使用Linux环境变量教程
2018-07-17 常见的web负载均衡方法总结