吐槽
先自我吐槽下,最近两天忙的比较晚,有点累,写作有点力不从心,所以今天来一篇短更,谈的话题也是跟面试相关的常见题引申而来,Spring AOP这个玩意感觉是“逢面必问”,当然对于一些“熟记硬背党”来说足以应付了,但是有没有想过,如果面试官反过来问,以“哪些情况不能用”来考察你对其原理的理解,是不是就有点懵了!笔者突然想到这个问题,决定以后这么问问看效果如何……
![734c48e759422b6bf22d5ed9c731ee1a.png](https://i-blog.csdnimg.cn/blog_migrate/da0662872fe3c96f9461ec129ab9c52c.jpeg)
进入正题
已说是短更,所以大致跟你们说一下,Spring AOP常被使用于事务切面,哪些方法不能实施AOP事务呢?当然要从AOP的实现原理上下手:
首先明确一点,Spring事务管理是基于接口代理或动态字节码技术,通过AOP来实施事务增强的(注意,Spring还支持AspectJ LTW在类加载期实施事务增强,只是这种方法极少使用,不作为本次讨论范畴)。
- 针对基于接口动态代理的情形
由于是接口,方法必然是public的,那么相应的也就要求实现的方法必须的public的,而不能是protected或private的,并且方法不能使用static修饰,这样就明确了,此类情形就只能使用public(注意,public final修饰是可以的),其他的方法将不能被动态代理,也就不能实施AOP增强了。
- 针对基于cglib字节码动态代理的情形
此情形是通过扩展被增强类,动态创建其子类的方式进行AOP增强植入的。由于使用final、static、private修饰的方法都不能被子类覆盖(注意,protected方法是可以被子类覆盖的,可以适用),所以这些方法也就无法实施AOP增强了。
总结+画龙点睛
上述不能实施Spring AOP增强的方法,并不是说它们就不在事务环境下工作了。注意,只要他们被外层的事务方法调用了,因Spring 事务管理的传播级别,这些被调用的内部方法也是同样可以工作在外部方法所启动的事务上下文中的。
强调下,上面所说的这些不适用的方法,指的是它们不能启动事务,但是并不影响外层方法的事务上下文传播到这些方法中。
最后,一句话概括:是否可以主动启动一个新事务,才是关键的关键!