Spring中申明式事务(@Transactional)实现的原理解析

前言

在Springboot中使用事务可以通过配置的方式以及声明式事务的方式去开启一个事务,对于申明式事务的使用,只需要在方法上面添加一个**@Transactional** 注解即可开启事务。但是让你看到最简单的事务,其实最神秘,如果没有真正的了解它也很容易使用错误导致出现问题。例如:什么情况下会导致事务失效、@Transactional注解中的各个属性应该在什么情况下使用(事务的传播特性、readOnly等)。只有真正的了解了声明式事务的原理之后才能够放心的去使用它。


一、Springboot中事务是如何自动配置

pringboot中的自动化配置都是通过在spring-boot-autoconfigure中的spring.factories文件中通过spi的方式进行引入的。打开这个spring.factories文件可以看到里面有一个TransactionAutoConfiguration,直接查看这个类的源码。

这里面引入了一个**@EnableTransactionManagement** 注解,之前使用Spring的时候就需要添加**@EnableTransactionManagement**去开启事务,所以这个注解是开启事务的入口。

这个注解通过@Import引入了TransactionManagementConfigurationSelector

这个类继承了AdviceModeImportSelector ,而AdviceModeImportSelector 是实现了ImportSelector 接口的。所以这个selectImports方法是想spring容器中注入了AutoProxyRegistrar 和ProxyTransactionManagementConfiguration。

二、 AutoProxyRegistrar的工作原理

AutoProxyRegistrar 实现了ImportBeanDefinitionRegistrar 接口,在Spring的扩展类中,ImportBeanDefinitionRegistrar 接口是实现了想Spring容器中注入Bean的作用,而这里向Spring容器中注入了AnnotationAwareAspectJAutoProxyCreator 和InfrastructureAdvisorAutoProxyCreator。AbstractAdvisorAutoProxyCreator 这个类就是创建Aop增强的关键。在之前关于Spring Aop的文章 《SpringBoot的AOP原理》中就已经说过。事务其实也是一种AOP增强,但是事务增强的实现是通过InfrastructureAdvisorAutoProxyCreator类来创建增强的。

根据 《SpringBoot的AOP原理》这篇文章,可以知道,Springboot是通过扩展点去一步一步的自行AOP增强的相关方法,先通过AbstractAutoProxyCreator#postProcessBeforeInstantiation 方法中获取切点和切面。这里的逻辑就跟AOP一模一样,都是调用的父类AbstractAutoProxyCreator 中的方法逻辑。唯一的不同点在于InfrastructureAdvisorAutoProxyCreator 没有重写findCandidateAdvisors方法,这个方法的主要逻辑是寻找Advisor的对象。

三、事务增强的代理类创建逻辑

前面已经完成了接入点和切面的查找了,后面就是怎么将这些切面织入到切入点,就是 《SpringBoot的AOP原理》中所说的创建代理对象的过程。这一步的主要逻辑就在getAdvicesAndAdvisorsForBean以及createProxy方法中,具体可以看一位大神写的文章《Spring源码深度解析》。而事务的具体逻辑就在Advisor和pointcut中,这一部分下次再说。


总结

事务其实也是AOP增强的一种,所以实现的原理也是跟AOP一样,只是具体的切面以及切入点的不同。

相关推荐
Rabitebla14 小时前
【Linux】 权限篇(三):深入理解 umask 位运算与粘滞位的设计思想
java·linux·服务器·c++·笔记·学习
IT_陈寒14 小时前
为什么你应该学习React?
前端·人工智能·后端
每天一道题14 小时前
Kafka 为什么会重复消费?从 Producer ACK、Offset 到消息可靠性
后端·微服务
Pin_Qing14 小时前
缓存能活多久,现在是个要算的参数
java·大数据·开发语言·人工智能·程序人生
jyOverQ14 小时前
从零开始学 RocketMQ(四):集群部署、消息存储与高可用【保姆级教程】
java·rocketmq·java-rocketmq
小裕哥略帅14 小时前
行级数据权限控制@DataPermission
java·开发语言
木易 士心15 小时前
Spring Boot 微信公众号后端服务开发实战指南
spring boot·后端·微信
ManageEngineITSM15 小时前
ITSM系统如何与企业微信、钉钉、飞书集成?提升工单处理效率的方法
java·大数据·开发语言·钉钉·企业微信·变更管理
BingoGo15 小时前
别再只用数组了,这 10 种 PHP 数据结构值得了解
后端·php
JaguarJack15 小时前
别再只用数组了,这 10 种 PHP 数据结构值得了解
后端·php·服务端