SpringAOP vs. JDK动态代理 vs. CGLib代理 vs. AspectJ代理 @Transactional的失效问题

1 AspectJ 是编译时增强的AOP框架,属于静态代理,但是代码组织上优于单纯使用java静态代理设计模式

2 SpringAOP 使用动态代理,与AspectJ没有任何关系,只不过使用了和AspectJ一样的注解,利用类似的概念、语法等(理解为向经典致敬),所以容易误认为SpringAOP使用AspectJ,如SpringAOP中的注解:@Aspect @Around @After,底层完全是SpringAOP自己一套东西


3 Spring 底层使用动态代理,可能是java原生动态代理,也可能是CGLib,默认规则如下
(1)如果实例实现了接口,如XxxServiceImpl implements XxxService,则底层使用JDK动态代理,比如@Transactional加到service方法上是JDK动态代理
(2)如果没有实现接口,类似在XxxController中的Http入口增强方法(如自定义增强注解:@ThirdToken),则使用CGLib代理,如在Http入口方法中答应容器中的XxxController.getClass(),出现如下:XxxController$$EnhancerBySpringCGLIB$$630fe5ae
(3)如果强制使用CGLib,则尽管实现接口类,也强制使用CGLib,但需要配置:

xml:
<aop:aspectj-autoproxy proxy-target-class="true"/>

注解(springboot只要加上AOP依赖后,默认是加上@EnableAspectJAutoProxy,只不过spring.aop.proxy-target-class=false)
@EnableAspectJAutoProxy(proxyTargetClass = true),默认情况下的代理使用原则,即不要配置proxy-target-class="true"

java动态代理主要依靠InvocationHandler实现,CGLib动态代理,主要依靠代理类继承父类,重写父方法实现

4 @Transactional内部调用失效
public class ASerivceImpl implements ASerivce{

     // 自注入
     @Autowared
     private ASerivce aService;
    
     public funcA(){
        this.funcB();
        aService.funcB();
     }

     @Transactional
     public funcB(){
     }
}
调用funcA,funcB上的事务注解是不起效的,因为相当于是this.funcB()是未被Spring增强过的方法,移动要从Spring容器中取出来的才是增强过的方法
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值