假如有方法A,方法A里有方法B,我们想对方法B进行事务控制。直接对方法B加事务注解,这样我们通过A调用B,事务会失效。
原因:
Spring 使用 AOP通过 代理对象 处理 @Transactional 注解的方法。除此以外还有一些注解修饰的方法也是通过代理对象来调用的,本质上是拦截之前的方法,用代理对象的增强逻辑来代替原来的逻辑。但是上面是内部调用,因为你是this,this 代表当前实例本身。this 不是 Spring 生成的代理对象,而是原始的目标对象,这样就无法拦截了,因为你直接调用了。但是你如果是外部类调用这个方法,还是可以拦截的到的。
为什么外部类调用该方法就可以拦截,内部类调用该方法就不能AOP拦截?
我的理解,本质上就是AOP是以bean为粒度的,你在bean内部怎么调用自己,都不会生成代理对象。
假如把methodA去掉,直接调用methodB,是可以生效的:
那么接下来又有问题了,为什么同样都是myService实例在调用,一个生效一个不生效 ?
本质上还是你内部调用的时候,确实是myService实例,但是你假如是在外部通过myService(外部生成的一个 bean)实例调用的时候,这个bean自动会被拦截,转为代理对象。