本文主要是介绍Spring AOP 方法内部调用不生效,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 问题描述
- 失效原因
- 解决方案
- 参考
问题描述
最近有个需求,统计某个方法的调用次数,开始使用 Spring AOP 实现,后来发现当方法被内部调用时,切面逻辑将不会生效,直接上样例:
定义接口,包含方法 A,方法 B
public interface ISon {void A();void B();
}
定义接口实现,方法 B 调用方法 A
@Service
public class Son implements ISon {@Overridepublic void A() {System.out.println("method A");}@Overridepublic 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 目标对象 直接调用,并不是代理对象进行调用
5.8. Proxying Mechanisms
解决方案
回到最开始的需求,如何通过切面的方式获取某一个方法的调用次数? 包括方法自调用
-
使用 AopContext.currentProxy()
切面开启注解
@EnableAspectJAutoProxy(exposeProxy = true,proxyTargetClass = true)
方法 B 不直接调用 A
@Overridepublic 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 方法内部调用不生效的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!