spring-boot 事务实现原理

文章讲述了如何在SpringBoot中实现动态事务管理,主要涉及@Transaction注解的使用、SpringBoot的bean管理、AOP流程以及TransactionInterceptor的作用。通过@EnableTransactionManagement开启事务管理,并由Spring自动配置事务管理器。TransactionAutoConfiguration类在启动时加载,配置事务管理相关组件。
一、 如何实现动态事务

如何实现其实就是遇到问题和解决问题的过程。

  1. 如何知道这个方法需要开启事务?
    答:只要给这个方法打上一个标记,有标记的方法就被认为需要开启事务。就像别人给你一块糖,不管它是什么糖,是大的、小的、方的、还是圆的。
  2. 虽然有了标记,但是这个标记如何被处理?
    答:需要能解析这个标记的程序来处理标记,也就是开启事务。
    就像别人给了你一块糖,你要能把糖吃到嘴里。如果你不知道如何打开包装,吃不到,那这个糖就不是糖了。

综上所述,我们需要两个东西来实现,一个是标记,另一个就是解析标记的程序。可以说spring体系下实现的功能大都需要这两样东西。

二、spring-boot 实现事务需要的基础知识
  1. spring-boot 查找bean的流程
  2. spring-context 初始化流程
  3. spring-aop 流程
三、spring-boot实现流程
  1. 把需要事务的对象交个spring管理
  2. 给需要的方法打上标记,即@Transactional 注解
  3. 把解析标记的程序交给spring。这个程序并不需要我们自己写,spring已经写好了,即TransactionInterceptor对象。默认spring-boot自动实现了这个流程。
  4. 需要spring-aop。@Transactional 标记的方法作为pointcut
    ,TransactionInterceptor作为advice。默认spring-boot自动实现了这个流程。
四、spring-boot事务实现原理

实现原理,主要写上面所说的3,4两个流程。

  1. spring-boot 查找bean的流程中其中一步是读取jar文件下的spring.factories文件并加载其中的类。这里加载了org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration 类。下面是这个类部分代码。
public class TransactionAutoConfiguration {

public static class EnableTransactionManagementConfiguration {

           @Configuration(proxyBeanMethods = false)
           @EnableTransactionManagement(proxyTargetClass = true)//这个注解是事务实现的入口
           @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
 matchIfMissing = true)
           public static class CglibAutoProxyConfiguration {
           }
     }
}

  1. @EnableTransactionManagement 加载了两个对象
  • org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration :将@Transactional标记包装成切点,TransactionInterceptor包装advice,创建了实现Advisor(aop 使用该接口)接口的对象
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

    //该bean实现了Advisor接口,aop会查找该接口的对象,并实现调用代理transactionInterceptor中的开启事务方法
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
			TransactionAttributeSource transactionAttributeSource,
			TransactionInterceptor transactionInterceptor) {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource);
		advisor.setAdvice(transactionInterceptor);
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

   //代表@Transactional 注解的对象
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor(
			TransactionAttributeSource transactionAttributeSource) {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource);
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}
  • org.springframework.context.annotation.AutoProxyRegistrar :开启aop能力;向spring注入了org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 对象,该对象会拦截其他对象的创建并生成代理对象;AnnotationAwareAspectJAutoProxyCreator 实现了BeanPostProcessor,在spring-context加载bean的流程中会调用如下方法(AnnotationAwareAspectJAutoProxyCreator祖先类中定义)

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
               if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                     // 这里会查找所有实现Advisor接口的对象,并生成代理对象
                     return wrapIfNecessary(bean, beanName, cacheKey);
                }
           }
           return bean;
}

五、图示

请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值