Spring深入刨析声明式事务注解的源码
作者:悠然予夏 发布时间:2023-10-23 09:41:48
声明式事务很方便,尤其纯注解模式,仅仅几个注解就能控制事务了
思考:这些注解都做了什么?好神奇!
@EnableTransactionManagement @Transactional
1、@EnableTransactionManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
@EnableTransactionManagement 注解使用@Import 标签引入了TransactionManagementConfigurationSelector类,这个类又向容器中导入了两个重要的组件
2、加载事务控制组件
2.1、AutoProxyRegistrar
AutoProxyRegistrar 类的 registerBeanDefinitions ⽅法中⼜注册了⼀个组件
进入AopConfigUtils.registerAutoProxyCreatorIfNecessary 方法
发现最终,注册了⼀个叫做 InfrastructureAdvisorAutoProxyCreator 的 Bean,而这个类是AbstractAutoProxyCreator 的子类,实现了 SmartInstantiationAwareBeanPostProcessor 接口
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
继承体系结构图如下
它实现了SmartInstantiationAwareBeanPostProcessor,说明这是⼀个后置处理器,而且跟spring AOP 开启@EnableAspectJAutoProxy 时注册的 AnnotationAwareAspectJProxyCreator实
现的是同⼀个接口,所以说,声明式事务是 springAOP 思想的⼀种应用
2.2、ProxyTransactionManagementConfiguration 组件
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
// 事务增强器
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
// 向事务增强器中注⼊ 属性解析器 transactionAttributeSource
advisor.setTransactionAttributeSource(transactionAttributeSource());
// 向事务增强器中注⼊ 事务 * transactionInterceptor
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// 属性解析器 transactionAttributeSource
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// 事务 * transactionInterceptor
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
ProxyTransactionManagementConfiguration是⼀个容器配置类,注册了⼀个组件transactionAdvisor,称为事务增强器,然后在这个事务增强器中又注入了两个属性:transactionAttributeSource,即属性解析器transactionAttributeSource 和 事务 * transactionInterceptor
属性解析器 AnnotationTransactionAttributeSource 部分源码如下
属性解析器有⼀个成员变量是annotationParsers,是⼀个集合,可以添加多种注解解析器(TransactionAnnotationParser),我们关注 Spring 的注解解析器,部分源码如下
属性解析器的作⽤之⼀就是⽤来解析@Transaction注解
TransactionInterceptor 事务 * ,部分源码如下
2.3、上述组件如何关联起来的
事务 * 实现了MethodInterceptor接口,追溯⼀下上面提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执行目标方法的时候获取其 * 链,而 * 链就是这个TransactionInterceptor,这就把这两个组件联系起来;
构造方法传⼊PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯一下上⾯贴的ProxyTransactionManagementConfiguration的源码,在注册事务 * 的时候并没有调用这个带参构造方法,而是调用的无参构造方法,然后再调用set方法注⼊这两个属性,效果⼀样。
2.4、invokeWithinTransaction⽅法
部分源码如下(关注1、2、3、4 标注处)
来源:https://blog.csdn.net/weixin_52851967/article/details/125533626


猜你喜欢
- 这篇文章主要讲述服务追踪组件zipkin,Spring Cloud Sleuth集成了zipkin组件。一、简介Add sleuth to
- Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。基于项
- 如有错误,望指正;SpringBoot可以有三种方式定义初始化器,来为容器中增加自定义的对象,具体如下:1、定义在spring.factor
- 下面先看一下效果图using UnityEngine;using System.Collections;public class textM
- 添加群机器人可以查看这篇文章:添加机器人到钉钉群 使用命令行工具curl快速验证自定义机器人是否可以正常工作。可以使用如下命令,把对应的链接
- 写了一个java数组排序示例,这里分享给大家共同学习package com.yonyou.test;import java.util.Arr
- 前言在Android设备内存动不动就上G的情况下,的确没有必要去太在意APP对Android系统内存的消耗,但在实际工作中我做的是教育类的小
- 一、业务需求实现省份与城市的二级联动二、实现效果三、代码实现1. province_city.jsp前端界面实现<%@ p
- 本文实例为大家分享了Android app应用实现多语言切换功能,供大家参考,具体内容如下1.添加多语言文件 在不同的 value 文件夹下
- 下文我们介绍两种双击事件拦截的方式1.通过Android的事件分发机制进行拦截(dispatchTouchEvent)话不多说,直接上代码:
- 这篇文章主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或
- 前言植物大战僵尸的数据文件是存储在本地的dat文件当中,修改在本地的dat文件就可以修改到游戏中的数据。之前使用二进制编码工具Hex Edi
- 本文所需的数据库初始文件,Hibernate常用操作的完整示例代码(包含所有Hibernate操作所需jar文件)提供下载学习:http:/
- 1、自定义消息转换器MessageConverter在WebMvcAutoConfiguration类中有一个方法configureMess
- 本文实例为大家分享了java实现捕鱼达人游戏的具体代码,供大家参考,具体内容如下效果图如下:源代码分享:测试类:package game;i
- import java.io.*;import java.text.SimpleDateFormat;import java.util.*;
- 四道Java基础题,你能对几道?一、==符的使用首先看一段比较有意思的代码Integer a = 1000,b=1000; Integer
- 一、Filter(过滤器)Filter接口定义在javax.servlet包中,是Servlet规范定义的,作用于Request/Respo
- 释一:属性的访问器包含与获取(读取或计算)或设置(写)属性有关的可执行语句。访问器声明可以包含 get 访问器或 set 访问器,或者两者均
- 实现方式和继承方式有什么区别呢?*区别:*继承Thread:线程代码存放在Thread子类run方法中*实现Runnable:线程代码存放在