Spring声明式事务之源码分析

开启事务的注解

@EnableTransactionManagement
此注解有一个由spring导入第三方的类:
Spring声明式事务之源码分析_第1张图片

TransactionManagementConfigurationSelector

①:AutoProxyRegistrar.class
该类实现了ImportBeanDefinitionRegistrar接口,用于预定义bean的注册,之后调用aop的方法
Spring声明式事务之源码分析_第2张图片Spring声明式事务之源码分析_第3张图片一个是spring初始化的时候,bean要实现的接口,Ordered,
一个是预定义bean在诸如的时候的名称,注入的流程术语ioc分域。

  • The bean name of the internally managed auto-proxy creator.
    */
    public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
    “org.springframework.aop.config.internalAutoProxyCreator”;
    ②:ProxyTransactionManagementConfiguration.class
    Spring声明式事务之源码分析_第4张图片解释:
    ①是事物的属性配置的方法
    看如下图:
    Spring声明式事务之源码分析_第5张图片红线标注的是对spring容器加入@Tranction的事务属性进行配置
    如下图,进行解析
    Spring声明式事务之源码分析_第6张图片
    ②昰事务的拦截器的方法
    如下图,将事务属性资源的属性设置到事务拦截器方法
    Spring声明式事务之源码分析_第7张图片## 事务连接器的类以及说明
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

    /**
     * Create a new TransactionInterceptor.
     * <p>Transaction manager and transaction attributes still need to be set.
     * @see #setTransactionManager
     * @see #setTransactionAttributes(java.util.Properties)
     * @see #setTransactionAttributeSource(TransactionAttributeSource)
     */
    public TransactionInterceptor() {
    }/**
     * Create a new TransactionInterceptor.
     * @param ptm the default transaction manager to perform the actual transaction management
     * @param tas the attribute source to be used to find transaction attributes
     * @see #setTransactionManager
     * @see #setTransactionAttributeSource(TransactionAttributeSource)
     */
    public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
        setTransactionManager(ptm);
        setTransactionAttributeSource(tas);
    }


    @Override
    @Nullable
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // Work out the target class: may be {@code null}.
        // The TransactionAttributeSource should be passed the target class
        // as well as the method, which may be from an interface.
        Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

        // Adapt to TransactionAspectSupport's invokeWithinTransaction...
        return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
    }

}

需要注意的两点:

① 事务拦截器实现了MethodInterceptor接口,这又是在springAOP中提到的拦截器链(https://www.cnblogs.com/dubhlinn/p/10708454.html),追溯一下上面提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执行目标方法的时候获取其拦截器链,而拦截器链就是这个TransactionInterceptor,这就把这两个组件联系起来了;

② 构造方法传入PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯一下上面贴的ProxyTransactionManagementConfiguration的源码,在注册事务拦截器的时候并没有调用这个带参构造方法,而是调用的无参构造方法,然后再调用set方法注入这两个属性,效果也是一样的。
然后我们继续跟进粉色粗体的invokeWithinTransaction方法的源码,看看触发的方法里面执行了什么
如下图:
Spring声明式事务之源码分析_第8张图片① 获取属性解析器,即在ProxyTransactionManagementConfiguration容器配置类中注册事务拦截器时注入的;
②determineTransactionManager方法
Spring声明式事务之源码分析_第9张图片spring会先根据qualifier,即@Transactional注解的value属性去获取,但是这个我们一般都不配置,只要在容器中有注册过PlatformTransactionManager类型的事务管理器,就可以直接通过类型来获取
③ 如果目标方法抛异常,会执行completeTransactionAfterThrowing,跟进一下源码:
Spring声明式事务之源码分析_第10张图片拿到事务管理器、执行回滚;

④ 如果目标方法正常运行,则会执行commitTransactionAfterReturning,同样跟进一下源码:
Spring声明式事务之源码分析_第11张图片

总结一下基于注解的声明式事务的原理:

  1. 在容器配置类上使用@EnableTransactionManagement注解,该注解在容器中注册了两大组件——AutoProxyRegistrar、ProxyTransactionManagementConfiguration;

  2. AutoProxyRegistrar通过导入方式在容器中注册了InfrastructureAdvisorAutoProxyCreator,这是一个后置处理器;

  3. ProxyTransactionManagementConfiguration本身就是一个容器配置类,它注册了transactionAdvisor(事务增强器),然后又在这个事务增强器中注入了两个属性transactionAttributeSource、transactionInterceptor;

  4. transactionAttributeSource用于解析@Transactional注解的各种属性;

  5. transactionInterceptor实现了MethodInterceptor,是一个拦截器链,这个拦截器链会从容器中获取事务管理器,利用事务管理器,在目标方法发生异常时执行回滚,在目标发生正常完成后提交事务;

  6. 第2步的InfrastructureAdvisorAutoProxyCreator后置处理器,会在目标对象创建完成之后将其包装为代理对象,代理对象在执行目标方法时会首先获取拦截器链,这个拦截器链就是第5步的transactionInterceptor。

你可能感兴趣的:(spring)