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容器中注入了AutoProxyRegistrarProxyTransactionManagementConfiguration。

二、AutoProxyRegistrar的工作原理

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

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

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

前面已经完成了接入点和切面的查找了,后面就是怎么将这些切面织入到切入点,就是 《SpringBoot的AOP原理》中所说的创建代理对象的过程。而这篇博客里面指出了创建AOP代理对象的时机是在InstantiationAwareBeanPostProcessor的后置方法postProcessAfterInitialization中调用了wrapIfNecessary

 而这一步的主要逻辑就在getAdvicesAndAdvisorsForBean以及createProxy方法中,具体可以看一位大神写的文章《Spring源码深度解析》。getAdvicesAndAdvisorsForBean方法是查找了容器内的所有Advisor切面以及Pointcout切入点,并将需要增强的方法匹配到具体的切入点。根据大神的文章,可以知道,Pointcout完成具体需要增强的方法匹配,Advisor则是具体增强的逻辑,事务的具体逻辑就在Advisor和pointcut中,而事务的切面和切入点都是在ProxyTransactionManagementConfiguration中注入容器的。具体的切入点和切面逻辑下篇文章再细谈。

先做个整体的了解,进入AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorForBean

两个方法,一个是查找切点和切面,一个是类和方法匹配到具体的切点和切面。查找切面主要是找出Advisor类型的Bean以及有@Aspect注解的类 。这里就不深入进去看了,主要看一下是怎么匹配到方法的。

代码调用的很多,这里就直接引用大神的结论了

pointcut.getClassFilter().matches(targetClass)返回true
pointcut.getMethodMatcher().matches(method, targetClass)返回true

所以主要逻辑在pointcut中。

总结

事务其实也是AOP增强的一种,所以实现的原理也是跟AOP一样,只是具体的切面以及切入点的不同。下一篇文章将针对事务的切面和切入点来分析事务实现的具体逻辑。

  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值