首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Spring事务是如何应用到你的业务场景中的?

初衷

日常开发中经常用到@Transaction注解,那你知道它是怎么应用到你的业务代码中的吗?本篇文章将从以下两个方面阐述Spring事务实现原理:

解析并加载事务配置:本质上是解析xml文件将标签加载成 BeanDefinition 对象;

生成事务代理对象并运行:本质上是Spring AOP在事务这块的应用,将业务Bean替换成事务代理对象(JdkDynamicAopProxy:JDK代理,CglibAopProxy:CGLIB代理);

本文使用的源码版本是Spring 4.3.18.RELEASE,使用的是XML开启事务。

关键类

这里列出几个核心类,提前留个印象,后面会讲解什么时候调用

XmlBeanDefinitionReader?加载XML定义的Bean入口

TxNamespaceHandler?解析XML中的事务标签:advice、annotation-driven等;

InfrastructureAdvisorAutoProxyCreator?该类实现了 BeanPostProcessor 接口(可以在Bean初始化后进行替换),是生成事务代理类并替换的关键类;

AnnotationTransactionAttributeSource?用来解析业务方法使用注解 @Transaction 上的配置,提供给 TransactionInterceptor 使用;

TransactionInterceptor?事务拦截类:真正处理事务的类,开启、回滚事务,可以理解成切面中的通知:做什么;

BeanFactoryTransactionAttributeSourceAdvisor?实现了Advisor接口,可以理解为切面:切点(TransactionAttributeSourcePointcut) + 通知(TransactionInterceptor)。

示例代码:

1. 解析并加载事务配置

加载的入口(同时也是Spring容器加载的核心代码):

事务配置的解析在上面的obtainFreshBeanFactory,由于我们使用的是ClassPathXmlApplicationContext 作为容器,它的解析类为:XmlBeanDefinitionReader;核心方法:

TxNamespaceHandler 最终交给类 AnnotationDrivenBeanDefinitionParser 进行解析事务配置;

到这里,事务配置的加载就结束了,上面的步骤只是将事务的关键类变成 BeanDefinition,实际上还没有生成Bean对象的,下面我们看下BeanDefinition 是如何变成Bean的(这一个步骤不是Spring事务独有的,是所有BeanDefinition 的共同逻辑),然后是如何生成业务bean代理对象并替换业务bean的。

2. 生成事务代理对象

入口在1.解析并加载事务配置列举的finishBeanFactoryInitialization(beanFactory) 方法中:

beanFactory.preInstantiateSingletons() 具体方法如下:

getBean(beanName) 方法比较复杂,这里只列举出关键点:AbstractAutowireCapableBeanFactory 的 initializeBean方法,所有bean的创建都绕不开这个方法,这个方法是执行实现了 BeanPostProcessor 的bean的逻辑:

InfrastructureAdvisorAutoProxyCreator 的 postProcessAfterInitialization 定义在父类:AbstractAutoProxyCreator,AbstractAutoProxyCreator这个类同时是Spring AOP处理的入口,并不是说事务处理独有的,具体实现如下:

proxyFactory.getProxy(getProxyClassLoader()) 方法实现:

通过2. 生成事务代理对象,此时创建的bean就是以及被JDK或者CGLIB代理的类,这一步是Spring AOP通用的处理逻辑,那具体是怎么运行的呢?

JDK动态代理运行:

CGLIB代理运行:

事务的最终执行类 TransactionInterceptor 的invoke 方法:

总结

以上就是事务应用到业务场景中的原理,可以简单理解:Spring事务是在Spring AOP的基础上开发的,关注关键类:TransactionInterceptor 的实现就行了,不管是JDK动态代理还是CGLIB代理都是要用到这个类去提交/回滚事务的。如有错误欢迎指出。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200915A02INW00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com