spring事务源码底层实现

spring的事务有两种,一种是声明是事务,一种是编程式事务,这里我们讲的是基于注解实现的方式,为什么我们在一个方法上面加上一个@Transactional注解,程序就能自动管理我们的本地事务,我们知道在SpringBoot项目中要用到Spring的事务,在启动配置类上面要加一个@EnableTransactionManagement,我们看看这个注解为我们做了些什么东西,

spring事务源码底层实现_第1张图片

可以很明显看到这个是一个组合注解,通过Import注解给我们导入了一个叫做TransactionManagementConfigurationSelector的一个selector,熟悉spring源码的应该知道selector,和registar是spring提供了两个扩展点,在spring容器启动时候,在解析配置类转换为BeanDefinition定义时候,会完成相应的解析处理,继续看这个TransactionManagementConfigurationSelector类

spring事务源码底层实现_第2张图片

spring容器启动的时候,当解析这个selector时候会回调这个selectImports方法,这里就会进入PROXY分支,为我们注册一个AutoProxyRegistar,和一个ProxyTransactionManagementConfiguration配置类。分别进入这两个类里面,

spring事务源码底层实现_第3张图片

AutoProxyRegistar实现了ImportBeanDefinitionRegistar,在容器启动解析配置文件的时候会触发registerBeanDefinitions方法,在这个方法里面会调用到AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)这个方法,继续点击进去

@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
   return registerAutoProxyCreatorIfNecessary(registry, null);
}
registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source)

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
      Class cls, BeanDefinitionRegistry registry, @Nullable Object source) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

   if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
      BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
      if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
         int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
         int requiredPriority = findPriorityForClass(cls);
         if (currentPriority < requiredPriority) {
            apcDefinition.setBeanClassName(cls.getName());
         }
      }
      return null;
   }

   RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
   beanDefinition.setSource(source);
   beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
   beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
   registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
   return beanDefinition;
}

最终会在容器里面注册和实例化一个叫InfrastructureAdvisorAutoProxyCreator的类,而这个类的继承关系可以看到

spring事务源码底层实现_第4张图片

这个类实现了BeanPostProcessor后置处理器,在创建bean的时候会调用后置处理器,完成一些bean的扩展和增强,spring容器启动实例化Bean的时候会调用BeanPostProcessor的postProcessAfterInitialization方法将所有加了@Trancation注解的方法封装到一个个advistor到代理类里面,后续方法调用的时候会拿出来处理

ProxyTransactionManagementConfiguration配置类里面实例化了几个重要的类,
BeanFactoryTransactionAttributeSourceAdvisor 封装了事务切面的信息
TransactionAttributeSource 封装了事务属性信息
TransactionInterceptor 拦截事务方法执行的类

spring事务源码底层实现_第5张图片

我们知道spring的事务是基于aop实现的,以jdk的动态代理来说,在带有事务注解的方法执行有事务的方法会调用到

JdkDynamicAopProxy这个类的invoke方法,我们看看这个invoke方法是如何执行的

spring事务源码底层实现_第6张图片 

 这里会将前面spring容器启动时候封装的Advisor对象,转换一个拦截器链路,然后循环调用,在这里这个拦截器链是不为空的,所以会走else分支里面的逻辑,接着会调用invocation.proceed()方法

spring事务源码底层实现_第7张图片

这里会走到else的invoke方法,最终会调用到TransactionInterceptor的invoke方法

spring事务源码底层实现_第8张图片

这里看到了关键的invokeWithinTransaction方法,跟进去

spring事务源码底层实现_第9张图片

 

 这里有两个关键的方法,我们分别进去看看

spring事务源码底层实现_第10张图片

 

 spring事务源码底层实现_第11张图片

 很显然在捕获异常的时候进行了手动回滚事务,业务方法正常执行的情况就手动提交事务,到这里Spring事务源码分析就结束了

你可能感兴趣的:(源码,java,spring,spring,boot)