核心类

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源码分析笔记--事务管理的更多相关文章

  1. Spring源码分析笔记--AOP

    核心类&方法 BeanDefinition Bean的定义信息,封装bean的基本信息,从中可以获取类名.是否是单例.是否被注入到其他bean中.是否懒加载.bean依赖的bean的名称等. ...

  2. Spring源码分析之`BeanFactoryPostProcessor`调用过程

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 本文内容: AbstractApplicationContext#refresh前部分的一点小内容 ...

  3. Spring源码分析之Bean的创建过程详解

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...

  4. Spring源码分析之循环依赖及解决方案

    Spring源码分析之循环依赖及解决方案 往期文章: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostPro ...

  5. Spring源码分析之AOP从解析到调用

    正文: 在上一篇,我们对IOC核心部分流程已经分析完毕,相信小伙伴们有所收获,从这一篇开始,我们将会踏上新的旅程,即Spring的另一核心:AOP! 首先,为了让大家能更有效的理解AOP,先带大家过一 ...

  6. Spring 源码学习笔记11——Spring事务

    Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...

  7. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  8. Spring源码分析专题 —— 阅读指引

    阅读源码的意义 更深入理解框架原理,印象更深刻 学习优秀的编程风格.编程技巧.设计思想 解决实际问题,如修复框架中的bug,或是参考框架源码,结合实际业务需求编写一个独有的框架 阅读源码的方法 首先是 ...

  9. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

随机推荐

  1. 学习Spring5必知必会(6)~Spring DAO

    一.Spring 对持久层技术的支持 Spring DAO 1.模板类: 2.基类: 二.spring JDBC [JDBCTemplate 模板类] 1.案例:使用jdbc 完成crud操作 (1) ...

  2. BI报表系统该如何集成到其他系统呢?

    近期小麦我经常收到很多用户的反馈,想知道Smartbi的报表能不能从微信/钉钉之类的直接跳转到已做好的报表页面?他们都希望通过这种方式尽可能地避免由于各个管理软件账号密码不同而造成的不便,能够在日常工 ...

  3. XStart远程连接Linux图形化界面

    转至:https://zhuanlan.zhihu.com/p/337791712 场景: 因在Linux中安装Oracle11g 需要调用Oracle的图形化界面,此时在宿主机上安装了 Xmanag ...

  4. Pycharm:运行程序时,不额外打开一个Console

    每次运行程序,比如A.py,都会额外生成一个Console,排列成一排的 A(2),A(3),... 那么如何关闭呢? 答案是:在Settings->Console中,勾选  'Use exis ...

  5. k8s-ingress部署测试以及深入理解

    1.ingress 部署有两种方式.本次采用DaemonSet部署. apiVersion: v1 kind: Namespace metadata: name: ingress-nginx --- ...

  6. Linux CentOS7.X-安装mysql5.7数据库(安装包tar.gz)

    一.下载对应版本的mysql 1.官网下载压缩安装包. 进入到mysql官网下载自己对应版本的mysql,下载地址:https://dev.mysql.com/downloads/mysql/5.7. ...

  7. 自定义 serializers.ValidationError 的错误返回

    在使用DRF进行反序列过程中,总是需要校验字段,然后返回错误结果.可以使用默认的自定义校验项,也可以自定义校验项.而默认的自定义校验项总是差强人意. 版本 Django 2.2.3 Python 3. ...

  8. Hive数仓

    分层设计 ODS(Operational Data Store):数据运营层  "面向主题的"数据运营层,也叫ODS层,是最接近数据源中数据的一层,数据源中的数据,经过抽取.洗净. ...

  9. 使用 Xshell 连接矩池云 GPU服务器

    下单租用 租用成功 打开软件 完成 错误用法不能这样使用

  10. 超强视频超分AI算法,从此只看高清视频

    最近发现一个特别强的视频超分算法----BasicVSR,在真实世界数据集中,实现了前所未有的视觉重建效果,最近它还拿下了超分比赛NTIRE 2021三冠一亚的优异成绩,登上了CVPR 2022. 视 ...