框架源码专题-Spring-5、声明式事务
1. 源码原理
@EnableTransactionManagement 的作用原理
1.1. @Import 使用方法
Spring-1、基本原理@Import 使用方法
1.2. @ EnableTransactionManagement
1.2.1. 注册时机
与 AOP 的注册时机是相同的:
BD 注册:在 refresh() 的第 5 步,invokeBeanFactoryPostProcessors
,如下图所示,方法执行完毕后,事务相关 BD 都已注册完毕
1.2.2. TransactionManagementConfigurationSelector⭐️🔴
利用 TransactionManagementConfigurationSelector
给容器中会导入 2 个组件
- AutoProxyRegistrar 注册器 (loadBeanDefinitionsFromRegistrars) ❕
- ProxyTransactionManagementConfiguration 配置类
1.2.3. AutoProxyRegistrar ①
1.2.3.1. 注册 InfrastructureAdvisorAutoProxyCreator
AutoProxyRegistrar 实现了 ImportBeanDefinitionRegistrar
接口,会调用实现的 registerBeanDefinitions
方法,给容器中注册一个 InfrastructureAdvisorAutoProxyCreator
组件;
1.2.3.2. 作用
InfrastructureAdvisorAutoProxyCreator 的作用?
利用后置处理器机制在对象初始化以后,包装对象,返回一个 代理对象(增强器)
,代理对象执行方法利用拦截器链进行调用;
1.2.4. ProxyTransactionManagementConfiguration ②
ProxyTransactionManagementConfiguration 做了什么?
1.2.4.1. 注册事务解析器
在初始化完成之后,BeanPostProcessor 的子接口 InstantiationAwareBeanPostProcessor 的子类 AbstractAutoPorxyCreator 会执行 postProcessAfterInitialization() 方法,在里面会创建动态代理
在创建过程中会解析@Transactional 注解,确定是否需要生成动态代理👇🏻
❕
❕
1.2.4.1.1. 事务解析器的作用⭐️🔴
- this.attributeCache.put(cacheKey, txAttr)
- 给出是否需要增强代理的判断
1.2.4.2. 注册事务拦截器 (配置事务管理器)
❕
1.2.4.3. 注册事务增强器 (advisor)⭐️🔴
给容器中注册事务增强器(BeanFactoryTransactionAttributeSourceAdvisor),然后 set事务注解解析器 和 事务拦截器
事务增强器要用事务注解的信息的时候,用 AnnotationTransactionAttributeSource
来解析事务注解
1.2.4.3.1. set 事务解析器 (AnnotationTransactionAttributeSource)
1.2.4.3.2. set 事务拦截器 (TransactionInterceptor)
1.2.5. 增强器的解析和缓存⭐️🔴
不同于 AOP,声明式事务没有切面逻辑,所以没有解析切面以及封装成 Advisor 的过程。它是直接给 new 了一个出来并通过@Bean 注册到容器中
在 AOP 的解析过程中,直接解析出来并缓存起来,然后在 findAdvisorsThatCanApply
方法中判断是否有 @Transactional
注解来确定是否为当前 Bean 生成动态代理 ❕
1.2.5.1. 继承关系
1.2.5.2. 缓存增强器
1.2.6. 判断是否需要增强⭐️🔴
^he1cd1
1.2.6.1. 判断入口
https://www.processon.com/diagraming/63e4bfa27c423a1934f127a5
❕
https://blog.csdn.net/paralysed/article/details/120398874
1.2.6.2. 判断方法⭐️🔴
如何判断当前类具备事务,具有创建动态代理的资格?
答:从==当前正在初始化的 bean 的==所有的方法中,找到带有@Transactional 的方法,根据方法优先原则,由本类方法 ==> 接口方法 ==> 父类方法的顺序去找,如果找到,就表示有创建动态代理的资格。如果方法上都没有,则去类上面找,由本类上 ==> 接口上 ==> 父类上的顺序去找,如果找到,就表示有创建动态代理的资格。
1.3. TransactionInterceptor⭐️🔴
1.3.1. 结构
- TransactionInterceptor:保存了
事务属性信息
和事务管理器
;
- extends TransactionAspectSupport implements MethodInterceptor
他是一个 MethodInterceptor;在目标方法执行的时候; 会执行拦截器链,就会进入拦截器中的方法
1.3.2. 执行
1.3.2.1. 获取 PlatformTransactionManager
1.3.2.2. 执行目标方法
如果异常,获取到事务管理器,利用事务管理回滚操作;
如果正常,利用事务管理器,提交事务
2. 实战经验
[[Spring注解驱动开发-尚硅谷-雷丰阳]]
2.1. 环境搭建
- 1、导入相关依赖
数据源、数据库驱动、Spring-jdbc 模块 - 2、配置数据源、JdbcTemplate(Spring 提供的简化数据库操作的工具)操作数据
spring-jdbc 会导入 2 个依赖
2.2. 重点配置
- 3、给方法上标注 @Transactional 表示当前方法是一个事务方法;
- 4、 EnableTransactionManagement 开启基于注解的事务管理功能;
- 5、配置事务管理器来控制事务;
@Bean
public PlatformTransactionManager transactionManager()
3. 参考与感谢
3.1. 尚硅谷 - 雷丰阳
3.1.1. 示例代码
spring-annotation: [[IOCTest_Tx.java]]