spring源码分析 事务

本文深入探讨了Spring框架中的声明式事务管理,从JDBC方式下的事务使用示例出发,逐步解析了事务自定义标签的配置、事务增强器的注册与应用。文章详细阐述了事务创建、回滚处理和提交的全过程,包括获取事务属性、处理已存在事务、设置事务信息等关键步骤,展示了Spring如何实现事务管理的高效与便捷。
摘要由CSDN通过智能技术生成

目录

JDBC方式下的事务使用示例

事务自定义标签

注册InfrastructureAdvisorAutoProxy-Creator

获取对应class/method的增强器

寻找候选增强器

候选增强器中寻找到匹配项

提取事务标签

事务增强器

创建事务

获取事务

处理已经存在的事务

准备事务信息

回滚处理

回滚条件

回滚处理

回滚后的信息清除

事务提交


注意:本文摘自 spring源码深度解析

 Spring声明式事务让我们从复杂的事务处理中得到解脱,使我们再也不需要去处理获得连接、关闭连接、事务提交和回滚等操作,再也不需要在与事务相关的方法中处理大量的try...catch...finally代码。Spring中事务的使用虽然已经相对简单得多,但是,还是有很多的使用及配置规则,有兴趣的读者可以自己查阅相关资料进行深入研究,这里只列举出最常用的使用方法。

同样,我们还是以最简单的示例来进行直观地介绍。

JDBC方式下的事务使用示例

在上面的测试示例中,UserServicelmpl类对接口UserService中的save函数的实现最后加入了一句抛出异常的代码: throw new RuntimeExceµtion("aa")。当注掉这段代码执行测试类,那么会看到数据被成功的保存到了数据库中,但是如果加入这段代码时再次运行测试类,发现此处的操作并不会将数据保存到数据库中。

汪意 默认情况下Spring中的事务处理只对RuntimeException方法进行回滚,所以,如果此处将Runtime Exception替换成普通的Exception不会产生回滚效果。

事务自定义标签

对于Spring中事务功能的代码分析,我们首先从配置文件开始入手,在配置文件中有这样一个配置:<tx:annotation-driven/>。可以说此处配翌是事务的开关,如果没有此处配置,那么Spring中将不存在事务的功能。那么我们就从这个配置开始分析。

根据之前的分析,我们因此可以判断,在自定义标签中的解析过程中一定是做了一些辅助操作,于是我们先从自定义标签入手进行分析。

使用Eclipse搜索全局代码,关键字annotation-drive,最终锁定类TxNamespaceHandler,在TxNamespaceHandler中的init方法中:

根据自定义标签的使用规则以及上面的代码,可以知道,在遇到诸如-<tx:annotation-driven为开头的配置后,Spring都会使用AnnotationDrivenBeanDefinitionParser类的parse方法进行解析。

在解析中存在对于mode属性的判断,根据代码,如果我们需要使用AspectJ的方式进行事务切入(Spring中的事务是以AOP为基础的),那么可以使用这样的配置:

注册InfrastructureAdvisorAutoProxy-Creator

我们以默认配置为例子进行分析,进入AopAutoProxyConfigurer类的configureAutoProxyCreator:

上面的代码注册了代理类及3个bean,很多读者会直接略过,认为只是注册3个bean而己,确实,这里只注册了3个bean,但是这3个bean支撑了整个的事务功能,那么这3个bean是怎么组织起来的呢?

首先,其中的两个bean被注册到了一个名为advisorDef的bean中,advisorDef使用BeanactoryTransactionAttributeSourceAdvisor作为其class属性。也就是说BeanFactoryTransactionAttributeSourceAdvisor代表着当前bean,如图所示,具体代码如下:

那么如此组装的目的是什么呢?我们暂且留下一个悬念,接着分析代码。上面函数configureAutoProxyCreator中的第一句貌似很简单但却是很重要的代码:

对于解析来的代码流程AOP中已经有所分析,上面的两个函数主要目的是注册了InfrastructureAdvisorAutoProxyCreator类型的bean,那么注册这个类的目的是什么呢?查看这个类的层次,如图所示。

从上面的层次结构中可以看到,lnfrastructureAdvisorAutoProxyCreator间接实现了SmartlnstantiationAwareBeanPostProcessor,而SmartlnstantiationAwareBeanPostProcessor又继承自InstantiationAwareBeanPostProcessor,也就是说在Spring中,所有bean实例化时Spring都会保证调用其rostProcessAfterInitialization方法,其实现是在父类AbstractAutoProxyCreator类中实现。

以之前的示例为例,当实例化userService的bean时便会调用此方法,方法如下:

这里实现的主要目的是对指定Bean进行封装,当然首先要确定是否需要封装,检测及封装的工作都委托给了wraplfNecessary函数进行。

wrapIfNecessary函数功能实现起来很复杂,但是逻辑上理解起来还是相对简单的,在wrapIfNecessary函数中主要的工作如下。

找出指定bean对应的增强器。根据找出的增强器创建代理。

听起来似乎简单的逻辑,Spring;中又做了哪些复杂的工作呢?对于创建代理的部分,通过之前的分析相信大家已经很熟悉了,但是对于增强器的获取,Spring又是怎么做的呢?

获取对应class/method的增强器

获取指定bean对应的增强器,其中包含两个关键字:增强器与对应。也就是说在getAdvicesAndAdvisorsForBean函数中,不但要找出增强器,而且还需要判断增强器是否满足要求。

其实我们也渐渐地体会到了Spring中代码的优秀,即使是一个很复杂的逻辑,在Spring中也会被拆分成若干个小的逻辑,然后在每个函数中实现,使得每个函数的逻辑简单到我们能快速地理解,而不会像有些人开发的那样,将一大堆的逻辑都罗列在一个函数中,给后期维护人员造成巨大的困扰。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值