Spring-事务源码解析1

一、使用

先说下使用,在SpringBoot启动类上加注解,表示开启声明式事务

开启事务注解
@EnableTransactionManagement

然后在Service方法上加

事务注解
@Transactional

二、实现逻辑

看下注解开启事务注解EnableTransactionManagement的源码

@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
      
}

@Import导入的类TransactionManagementConfigurationSelector,主要看selectImports方法

@Override
protected String[] selectImports(AdviceMode adviceMode) {
      switch (adviceMode) {//默认是PROXY
            case PROXY:
                  return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
            case ASPECTJ:
                  return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
            default:
                  return null;
      }
}

小结:其原理是通过@Import导入TransactionManagementConfigurationSelector组件,然后又通过TransactionManagementConfigurationSelector导入2个组件AutoProxyRegistrar、ProxyTransactionManagementConfiguration;

下面分别介绍下这个2个组件的作用

三、组件1:AutoProxyRegistrar

AutoProxyRegistrar向容器中注册一个DB=>InfrastructureAdvisorAutoProxyCreator

name = org.springframework.aop.config.internalAutoProxyCreator

AutoProxyRegistrar继承了几个重要的类

1、SmartInstantiationAwareBeanPostProcessor
2、InstantiationAwareBeanPostProcessor
3、BeanPostProcessor

这里就和AOP的AnnotationAwareAspectJAutoProxyCreator很类似了,父类都有SmartInstantiationAwareBeanPostProcessor

小结:组件AutoProxyRegistrar,会向容器中注册一个DB。这个DB说白了就是一个后置处理器,当Bean初始化的时候,会执行所有的后置处理器,包括这个后置处理器,目的就是通过这个后置处理器来给Bean创建代理对象。

疑问
启动前InfrastructureAdvisorAutoProxyCreator会做哪些事?

组件2:ProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration是一个事务管理配置类,引入这个配置类的目的就是为了会向Spring容器中注入Bean,下面介绍导入的这三类Bean

1、事务注解@Transactional的解析器(AnnotationTransactionAttributeSource) 。简称:@Transactional注解的解析类,类似于切点
2、事务方法拦截器(TransactionInterceptor)。 简称:事务方法的拦截器,类似于切面里的通知
3、事务增强器(BeanFactoryTransactionAttributeSourceAdvisor)。简称:事务增强器(Advisor) 类似于切面

这不就妥妥的AspectJ嘛,当Bean在初始化的时候,通过注解解析器判断类或者方法上带有@Transactional注解,就对这个Bean生成代理对象,并添加拦截方法,用于事务提交和回滚。

下面是三种Bean的具体实现类如下

@Configuration
ProxyTransactionManagementConfiguration{
     1@Bean BeanFactoryTransactionAttributeSourceAdvisor   切面
     2@Bean AnnotationTransactionAttributeSource           切点
     3@Bean TransactionInterceptor                         通知
}

看下事务管理配置类的具体源码

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
   
	  //1、定义注解解析器:内部通过SpringTransactionAnnotationParser类来处理@Transaction注解
      @Bean
      @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
      public TransactionAttributeSource transactionAttributeSource() {
            return new AnnotationTransactionAttributeSource();      
      }
	   
	  //2、事务方法拦截器TransactionInterceptor:实现了MethodInterceptor接口,主要用于拦截事务方法的执行
      @Bean
      @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
      public TransactionInterceptor transactionInterceptor() {
            TransactionInterceptor interceptor = new TransactionInterceptor();
            interceptor.setTransactionAttributeSource(transactionAttributeSource());
            if (this.txManager != null) {
                  interceptor.setTransactionManager(this.txManager);
            }
            return interceptor;
      }

	  //3、定义事务增强器:重点是用来绑定"事务注解解析器"和"事务方法拦截器"
      @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
      @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
      public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
            BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
            //依赖 @Transactional注解的解析类
            advisor.setTransactionAttributeSource(transactionAttributeSource());
            //依赖 事务方法拦截器
            advisor.setAdvice(transactionInterceptor());                        
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
            return advisor;
      }
}

“事务增强器” 里面有个属性TransactionAttributeSourcePointcut,它有个方法matches,该类会通过"事务方法解析器" ,来匹配目标方法是否带有事务注解。

@Override
public boolean matches(Method method, Class<?> targetClass) {
	  //拿到@Baan也就是AnnotationTransactionAttributeSource
      TransactionAttributeSource tas = getTransactionAttributeSource();
      //判断method是否带有@Transaction注解
      return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

小结:事务管理配置类引入3个Bean,这个3Bean就有点类似于切面、切点、通知的关系,通过这个三个东西完成对Bean的注解解析,方法拦截。最终得到我们要的代理对象。

总结:前面我们讲了EnableTransactionManagement这个注解会向Spring里面注入2个很关键的组件,一个是后置处理器,一个就是事务管理配置类,类似于切面。这2个组件的目的就是在Spring-Bean初始化的时候,调用后置处理器,后置处理器通过切面的规则判断@Transaction注解,来创建代理对象。

关于Spring如何利用上面2个组件创建Bean的代理对象请看《Spring-事务源码解析2》

你可能感兴趣的:(Spring整理后,Transaction,Spring,事务源码,事务拦截器,事务增强器,事务注解解析器,事务管理器)