Spring源码分析笔记--事务管理
核心类
InfrastructureAdvisorAutoProxyCreator
本质是一个后置处理器,和AOP的后置处理器类似,但比AOP的使用级别低。当开启AOP代理模式后,优先使用AOP的后置处理器。
AopConfigUtils:
/**
* The bean name of the internally managed auto-proxy creator.
*/
//和AOP一样都向容器注入以此为name的后置处理器,进行代理类的创建
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator"; /**
* Stores the auto proxy creator classes in escalation order.
*/
//按升级的顺序存储进行代理类创建的后置处理器
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>(); /**
* Setup the escalation list.
*/
//代理创建类后置处理器升级列表,下标越大等级越高
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
源码跟踪
查看注解@EnableTransactionManagement源码,通过@Import导入TransactionManagementConfigurationSelector类,在类的重写方法中可以看到向容器注入了两个类AutoProxyRegistrar、ProxyTransactionManagementConfiguration
AutoProxyRegistrar
用于向容器中注册事务管理用的后置处理器
==》org.springframework.context.annotation.AutoProxyRegistrar#registerBeanDefinitions
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
==》org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired
//此类下检查容器中是否有name为:"org.springframework.aop.config.internalAutoProxyCreator"的后置处理器bean,如果没有则注册,如果有则比较等级大小,若是等级大则对原beanDefination升级。例如:如果启用了AOP则不用升级
ProxyTransactionManagementConfiguration
配置事务管理所需的管理器、参数等
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
//类似AOP,这里创建了一个用于事务Advisor的Bean
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
return advisor;
}
//封装事务管理配置的参数,@Transactional(..)中的参数
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
//封装事务用的advice为Interceptor,并关联上了事务管理器
// TransactionInterceptor与AOP的Interceptor一样都继承自MethodInterceptor
//事务管理器主要用来控制事务,commit、rollback等
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
} }
运行时源码
运行时原理同AOP,对添加了@Transactional注解的类做代理,对被代理类的方法进行增强处理,执行一个拦截器链。跟踪进去可以发现Interceptor chain中多了一个TransactionIntercepor。通过此Interceptor在方法前开启事务,在方法后commit或rollback。

TransactionInterceptor
==》org.springframework.transaction.interceptor.TransactionInterceptor#invoke
==》 org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
// If the transaction attribute is null, the method is non-transactional.
//获取事务相关属性、管理器
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//开启一个事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//调用被代理类的方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//回滚事务
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
//提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
流程梳理
1、 创建后置处理器InfrastructureAdvisorAutoProxyCreator
2、 创建TransactionInterceptor,加入interceptor chain。
3、 对指定后置处理器为InfrastructureAdvisorAutoProxyCreator的bean使用TransactionInterceptor进行事务处理。
Spring源码分析笔记--事务管理的更多相关文章
- Spring源码分析笔记--AOP
核心类&方法 BeanDefinition Bean的定义信息,封装bean的基本信息,从中可以获取类名.是否是单例.是否被注入到其他bean中.是否懒加载.bean依赖的bean的名称等. ...
- Spring源码分析之`BeanFactoryPostProcessor`调用过程
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 本文内容: AbstractApplicationContext#refresh前部分的一点小内容 ...
- Spring源码分析之Bean的创建过程详解
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...
- Spring源码分析之循环依赖及解决方案
Spring源码分析之循环依赖及解决方案 往期文章: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostPro ...
- Spring源码分析之AOP从解析到调用
正文: 在上一篇,我们对IOC核心部分流程已经分析完毕,相信小伙伴们有所收获,从这一篇开始,我们将会踏上新的旅程,即Spring的另一核心:AOP! 首先,为了让大家能更有效的理解AOP,先带大家过一 ...
- Spring 源码学习笔记11——Spring事务
Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- Spring源码分析专题 —— 阅读指引
阅读源码的意义 更深入理解框架原理,印象更深刻 学习优秀的编程风格.编程技巧.设计思想 解决实际问题,如修复框架中的bug,或是参考框架源码,结合实际业务需求编写一个独有的框架 阅读源码的方法 首先是 ...
- Spring 源码学习笔记10——Spring AOP
Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...
随机推荐
- Windows原理深入学习系列-访问控制列表
这是[信安成长计划]的第 19 篇文章 0x00 目录 0x01 介绍 0x02 DACL 0x03 创建DACL 0x04 文件读取测试 0x05 进程注入测试 0x06 原理分析 Win10_x6 ...
- 3rd S-curve velocity profile
3rd S-curve (1) (2) (3) (4) 完整的三次S曲线包括上面的七个阶段.前面三个阶段为加速阶段,从初始速度Vs加速到Vmax: (5) 整个加速阶段的位移为: (6) 后面三个阶 ...
- JZ-012-数值的整数次方
数值的整数次方 题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 保证base和exponent不同时为0. 题目链接: 数值的 ...
- feign服务中调用,传递token
默认spring-boot 微服务中 用feign来做服务间调用,是不会携带token传递的.为了能让服务间调用的时候带上token,需要进行配置,增强resTemplate 1.先实现请求拦截器 ...
- Springboot循环依赖实践纪实
测试的Springboot版本: 2.6.4,禁止了循环依赖,但是可以通过application.yml开启(哈哈) @Lazy注解解决循环依赖 情况一:只有简单属性关系的循环依赖 涉及的Bean: ...
- 基于idea做java程序的本地k8s调试-skaffold(二)
上一篇讲完了java代码发到本机minikube中run,这篇来讲讲minkube中进行debug(idea下) 话说,上篇是把pigx基础infra微服务都发到了minikube中,这些微服务是ru ...
- myBatis plus 去除生成 controller
由于我在网上没有找到答案, 所以分享给大家学习, 我也是第一次用 mybtis plus 的新生成器生成代码, 所以基础代码都是在官网复制所得. 在这里也支持大家在解决不了问题时, 可以试着看看源 ...
- 31 面向对象编程 接口 普通类:只有具体实现 声明类的关键字是class,声明接口关键字是interface 接口的作用
接口 概念 普通类:只有具体实现 抽象类:具体实现和规范(抽象方法)都有! 接口:只有规范!自己无法写方法!专业的约束!约束和实现分离:面向接口编程~ 接口就是规范,定义的是一组规则,体现了现实世界中 ...
- 【ASP.NET Core】MVC 控制器的模型绑定(宏观篇)
欢迎来到老周的水文演播中心. 咱们都知道,MVC的控制器也可以用来实现 Web API 的(它们原本就是一个玩意儿),区别嘛也就是一个有 View 而另一个没有 View.于是,在依赖注入的服务容器中 ...
- 使用Github Action自动填写疫情通
使用Github Action自动填写疫情通 西电晨午晚检一天三次,通过企业号功能进行填写.实际上,西电企业号大部分功能是以网页模式工作的,通过构造connection发送合适的request,设置计 ...