Spring AOP方法内部调用不生效的解决方案
作者:菜鸟日常
最近有个需求,统计某个方法的调用次数,开始使用 Spring AOP 实现,后来发现当方法被内部调用时,切面逻辑将不会生效,所以本文就给大家介绍了Spring AOP方法内部调用不生效的解决方案,需要的朋友可以参考下
问题描述
最近有个需求,统计某个方法的调用次数,开始使用 Spring AOP 实现,后来发现当方法被内部调用时,切面逻辑将不会生效,直接上样例:
定义接口,包含方法 A,方法 B
public interface ISon { void A(); void B(); }
定义接口实现,方法 B 调用方法 A
@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(); } }
切点定义,对方法 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,会进行增强;但是如果是方法 B 调用,A 的增强逻辑将失效。
失效原因
方法 A 被调用,是基于 AOP 生成的 代理对象 进行的调用;方法 B 调用方法 A ,是 this 目标对象 直接调用,并不是代理对象进行调用
解决方案
回到最开始的需求,如何通过切面的方式获取某一个方法的调用次数? 包括方法自调用
使用 AopContext.currentProxy()
切面开启注解
@EnableAspectJAutoProxy(exposeProxy = true,proxyTargetClass = true)
方法 B 不直接调用 A
@Override public void B() { System.out.println("method B"); ((Son) AopContext.currentProxy()).A(); }
先获取上下文的 Bean 再调用
@Autowired private ApplicationContext applicationContext; ((Son) applicationContext.getBean(Son.class)).A();
以上就是Spring AOP方法内部调用不生效的解决方案的详细内容,更多关于Spring AOP方法调用不生效的资料请关注脚本之家其它相关文章!