• Spring源码分析笔记--事务管理


    核心类

    InfrastructureAdvisorAutoProxyCreator

    本质是一个后置处理器,和AOP的后置处理器类似,但比AOP的使用级别低。当开启AOP代理模式后,优先使用AOP的后置处理器。

    AopConfigUtils:

    /**
     * The bean name of the internally managed auto-proxy creator.
     */
    //和AOP一样都向容器注入以此为name的后置处理器,进行代理类的创建
    public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
          "org.springframework.aop.config.internalAutoProxyCreator";
    
    /**
     * Stores the auto proxy creator classes in escalation order.
     */
    //按升级的顺序存储进行代理类创建的后置处理器
    private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>();
    
    /**
     * Setup the escalation list.
     */
    //代理创建类后置处理器升级列表,下标越大等级越高
    static {
       APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
       APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
       APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
    }

    源码跟踪

    查看注解@EnableTransactionManagement源码,通过@Import导入TransactionManagementConfigurationSelector类,在类的重写方法中可以看到向容器注入了两个类AutoProxyRegistrar、ProxyTransactionManagementConfiguration

    AutoProxyRegistrar

    用于向容器中注册事务管理用的后置处理器

    ==》org.springframework.context.annotation.AutoProxyRegistrar#registerBeanDefinitions

           AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);

    ==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)

    ==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

    ==》org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired

    //此类下检查容器中是否有name为:"org.springframework.aop.config.internalAutoProxyCreator"的后置处理器bean,如果没有则注册,如果有则比较等级大小,若是等级大则对原beanDefination升级。例如:如果启用了AOP则不用升级

     

    ProxyTransactionManagementConfiguration

    配置事务管理所需的管理器、参数等

    @Configuration
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    //类似AOP,这里创建了一个用于事务Advisor的Bean
       @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
       @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
       public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
          BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
          advisor.setTransactionAttributeSource(transactionAttributeSource());
          advisor.setAdvice(transactionInterceptor());
          advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
          return advisor;
       }
    //封装事务管理配置的参数,@Transactional(..)中的参数
       @Bean
       @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
       public TransactionAttributeSource transactionAttributeSource() {
          return new AnnotationTransactionAttributeSource();
       }
    //封装事务用的advice为Interceptor,并关联上了事务管理器
    // TransactionInterceptor与AOP的Interceptor一样都继承自MethodInterceptor
    //事务管理器主要用来控制事务,commit、rollback等
       @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;
       }
    
    }

    运行时源码

    运行时原理同AOP,对添加了@Transactional注解的类做代理,对被代理类的方法进行增强处理,执行一个拦截器链。跟踪进去可以发现Interceptor chain中多了一个TransactionIntercepor。通过此Interceptor在方法前开启事务,在方法后commit或rollback。

    TransactionInterceptor

    ==》org.springframework.transaction.interceptor.TransactionInterceptor#invoke

    ==》 org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

    // If the transaction attribute is null, the method is non-transactional.
    //获取事务相关属性、管理器
    final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    
    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
       // Standard transaction demarcation with getTransaction and commit/rollback calls.
    //开启一个事务
       TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
       Object retVal = null;
       try {
          // This is an around advice: Invoke the next interceptor in the chain.
          // This will normally result in a target object being invoked.
    //调用被代理类的方法     
     retVal = invocation.proceedWithInvocation();
       }
       catch (Throwable ex) {
          // target invocation exception
        //回滚事务
          completeTransactionAfterThrowing(txInfo, ex);
          throw ex;
       }
       finally {
          cleanupTransactionInfo(txInfo);
       }
        //提交事务
       commitTransactionAfterReturning(txInfo);
       return retVal;
    }

    流程梳理

    1、 创建后置处理器InfrastructureAdvisorAutoProxyCreator

    2、 创建TransactionInterceptor,加入interceptor chain。

    3、 对指定后置处理器为InfrastructureAdvisorAutoProxyCreator的bean使用TransactionInterceptor进行事务处理。

    永葆一颗纯洁、仁慈和意气风发的心!
  • 相关阅读:
    SpringBoot 发送邮件
    @Component 爆红
    Java 调用OpenCV获取图像数据,发送Redis并从Redis获取数据显示
    xxx.bat windows Bat文件启动cmd命令运行jar包
    队列
    paramiko连接服务器
    matplotlib模块画坐标图
    获取当前时间
    jsonpath和打印模板
    提取图片中的文字
  • 原文地址:https://www.cnblogs.com/little-sheep/p/10115173.html
Copyright © 2020-2023  润新知