Spring事务与JDK/CGLIB动态代理

本文详细介绍了Spring事务管理中@Transactional注解的原理,以及JDK和CGLIB动态代理的区别。内容包括:1) Transactional注解如何驱动事务管理;2) JDK动态代理依赖于接口,而CGLIB通过继承目标类实现;3) 自调用导致的事务失效问题及原因;4) 非public方法不受事务管理支持的分析。总结了Spring AOP在事务处理中的应用及其局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 首先Spring事务在开发过程中是通过@Transactional注解来控制。

1. Transactional注解的原理

  • 对于使用了Transactional注解的方法的类,Spring AOP代理会在运行时生成这个类的代理对象。
  • 当这个对象运行这个注解方法时,会读取@Transactional注解里面配置的信息,决定该方法是否要使用TransactionInterceptor拦截器来拦截。
  • 当拦截器拦截该方法时,会在调用该方法之前,创建事务,并在这个事务中执行该方法,最后根据执行是否有异常使用抽象事务管理器(AbstractPlatformTransactionManager)操作数据源提交或者回滚这个事务。
  • 它本质使用一个事务拦截器,在方法调用的前后/周围进行事务性增强(advice),来驱动事务完成。也就是在业务方法外边通过Spring AOP包上一层事务管理器的代码(即插入切面),这是Java设计模式中常见的通过代理增强被代理类的做法。

2. JDK 和 CGLib动态代理区别

Spring AOP的底层有2种实现:JDK动态代理、CGLIB。

  • 前者的原理是JDK反射,并且只支持Java接口的代理;
  • 后者的原理是继承(extend)与覆写(override),因此能支持普通的Java类的代理。两种方式都是动态代理,即运行时实时生成代理。

由于JVM的限制,CGLIB无法替换被代理类已经被载入的字节码,只能生成并载入一个新的子类作为代理类,被代理类的字节码依然存在于JVM中。

  • 区别于前两者,AspectJ是一种静态代理的实现,即在编译时或者载入类时直接修改被代理类文件的字节码,而非运行时实时生成代理。因此这种方式需要额外的编译器或者JVM Agent支持,通过一些配置Spring和Aspe
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值