32.Spring事务原理之@EnableTransactionManagement

221 阅读8分钟

9.Spring事务原理之@EnableTransactionManagement

Spring提供的AOP功能有两种实现方式,可选值有PROXY 和 ASPECTJ,默认值为AdviceMode.PROXY。

一种是Spring自带的AOP功能,主要靠JDK代理和CGLIB代理实现,另外一种是通过第三方框架ASPECTJ实现。

@EnableTransactionManagement中的mode选项就是设定Spring用哪种方式提供AOP功能。

AdviceMode.PROXY表示用Spring自带的AOP功能,AdviceMode.ASPECTJ表示使用ASPECTJ提供AOP功能。

需要注意的是Spring自带的AOP功能不支持本地调用的代理功能,也就是说同一个类中的方法互相调用不会“触发”代理方法。

如果想让自调用触发代理,可以考虑使用ASPECTJ。

由于AdviceMode.PROXY应用比较广泛,而AdviceMode.ASPECTJ应用较少。所以我们主要是讲AdviceMode.PROXY。

参考:www.cnblogs.com/54chensongx…

@EnableTransactionManagement

/***
@EnableTransactionManagement注解有以下几个属性
proxyTargetClass属性:
指定事务的AOP是通过JDK动态代理实现,还是CGLIB动态代理实现。
true的话是CGLIB,false的话是JDK动态代理需要注意的是这个属性只有在AdviceMode设置成AdviceMode.PROXY的情况下才会生效。
假如使用ASPECTJ的AOP框架的话,这个属性就失效了。
另外,这个属性的设定可能会影响其他需要动态代理的类。
比如说将这个属性设置成true,@Async注解的方法也会使用CGLIB生成代理类。
但是总的来说,这个属性的设置不会造成什么负面影响,毕竟JDK动态代理和CGLIB动态代理都能实现我们的需求
​
mode属性:
Spring提供的AOP功能有两种实现方式,一种是Spring自带的AOP功能,主要靠JDK代理和CGLIB代理实现,另外一种是通过第三方框架ASPECTJ实现。
这个选项就是设定Spring用哪种方式提供AOP功能。AdviceMode.PROXY表示用Spring自带的AOP功能,AdviceMode.ASPECTJ表示使用ASPECTJ提供AOP功能。
需要注意的是Spring自带的AOP功能不支持本地调用的代理功能,也就是说同一个类中的方法互相调用不会“触发”代理方法。如果想让自调用触发代理,可以考虑使用ASPECTJ。
​
order属性:表示当一个连接点(方法)被切多次时(也就是说有多个Advice和连接点关联),这些连接点的执行顺序。
***/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
    
    //true:cglib  false:jdk
    boolean proxyTargetClass() default false;
​
     //默认是AdviceMode.PROXY
    AdviceMode mode() default AdviceMode.PROXY;
​
    int order() default Ordered.LOWEST_PRECEDENCE;
​
}
public enum AdviceMode {
    /**
     * JDK proxy-based advice.
     */
    PROXY,
    /**
     * AspectJ weaving-based advice.
     */
    ASPECTJ
}

TransactionManagementConfigurationSelector

注意是1个Selector

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    @Override
    protected String[] selectImports(AdviceMode adviceMode) {
        //这里的AdviceMode 由
        //AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来
        //就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY;
        switch (adviceMode) {
            case PROXY:
                //如果是 PROXY 那么返回的是 
                //AutoProxyRegistrar和ProxyTransactionManagementConfiguration
                return new String[] {AutoProxyRegistrar.class.getName(),
                        ProxyTransactionManagementConfiguration.class.getName()};
            case ASPECTJ:
                //如果是 ASPECTJ 那么返回的是
                /**
                 如果类加载器有"javax.transaction.Transactional"
                 那么创建AspectJJtaTransactionManagementConfiguration
                 否则创建AspectJTransactionManagementConfiguration
                 */
                return new String[] {determineTransactionAspectClass()};
            default:
                return null;
        }
    }
    //省略代码
}
​

TransactionManagementConfigurationSelector继承自AdviceModeImportSelector

所以这个代码

selector.selectImports(currentSourceClass.getMetadata());

进入的是

AdviceModeImportSelector#selectImports(AnnotationMetadata importingClassMetadata)

public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {


	public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";

	protected String getAdviceModeAttributeName() {
		return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
	}

	@Override
	public final String[] selectImports(AnnotationMetadata 
                                        	importingClassMetadata) {
		Class<?> annType = GenericTypeResolver.resolveTypeArgument
            				(getClass(), AdviceModeImportSelector.class);
		 
		 /***
        @EnableAspectJAutoProxy(proxyTargetClass = true)
        @EnableTransactionManagement
        @ComponentScan("transaction")
        public class BeanConfig {
        }
        因为TransactionManagementConfigurationSelector
        是被@EnableTransactionManagement导入的
        @EnableTransactionManagement加在了BeanConfig上面
 		所以读取的metadata是BeanConfig上面的注解元数据
 		元数据:是3个注解的值
		 0 =  EnableAspectJAutoProxy
		 			(proxyTargetClass=false, exposeProxy=false)"
		 1 =  EnableTransactionManagement
		 			(mode=PROXY, order=2147483647, proxyTargetClass=false)"
		 2 =  ComponentScan
		 			(scopeResolver=class org.springframework.context.annotation.AnnotationScopeMetadataResolver, lazyInit=false, resourcePattern=**.class, useDefaultFilters=true, excludeFilters=[], scopedProxy=DEFAULT, basePackageClasses=[], nameGenerator=interface org.springframework.beans.factory.support.BeanNameGenerator, basePackages=[], value=[], includeFilters=[])"
		 */
		AnnotationAttributes attributes = 
            AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
		if (attributes == null) {
			throw new IllegalArgumentException();
		}
		 //这里的adviceMode 
        //由AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来
		//就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY;
		AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
		//调用TransactionManagementConfigurationSelector.selectImports导入组件
		String[] imports = selectImports(adviceMode);
		if (imports == null) {
			throw new IllegalArgumentException
                			("Unknown AdviceMode: " + adviceMode);
		}
		return imports;
	}

	@Nullable
	protected abstract String[] selectImports(AdviceMode adviceMode);
}

调用TransactionManagementConfigurationSelector.selectImports

public class TransactionManagementConfigurationSelector extends 					AdviceModeImportSelector<EnableTransactionManagement> {
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		//这里的AdviceMode 
        //由AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来
		//就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY;
		switch (adviceMode) {
			case PROXY:
				//如果是PROXY 那么返回的是
                //AutoProxyRegistrar和ProxyTransactionManagementConfiguration
				return new String[] {
                    	AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				//如果是 ASPECTJ 那么返回的是
                /**
                如果类加载器有"javax.transaction.Transactional"
                那么创建AspectJJtaTransactionManagementConfiguration
                否则创建AspectJTransactionManagementConfiguration
                JtaTransaction和Transaction
				 */
				return new String[] {determineTransactionAspectClass()};
			default:
				return null;
		}
	}

可以看到,如果是Proxy代理的话,会往spring ioc容器注入两个组件如下

AutoProxyRegistrar.class和ProxyTransactionManagementConfiguration.class

AutoProxyRegistrar

而AutoProxyRegistrar又是个BeanDefinitionRegistrar,所以它又给容器导入了一些组件

这个BeanDefinitionRegistrar也是往容器注入组件的工具,看看它的registerBeanDefinitions方法

又注入了什么组件?

模式1:Proxy

导入:AutoProxyRegistrar

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
        registrars.forEach((registrar, metadata) ->
                registrar.registerBeanDefinitions(metadata, this.registry));
    }

解析mode和proxyTagetClass

注入InfrastructureAdvisorAutoProxyCreator

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
​
    private final Log logger = LogFactory.getLog(getClass());
      
    //importingClassMetadata是beanConfig上的注解集合
    @Override
    public void registerBeanDefinitions(AnnotationMetadata 
                                        importingClassMetadata,
                                        BeanDefinitionRegistry registry) {
        boolean candidateFound = false;
        Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
        for (String annType : annTypes) {
            AnnotationAttributes candidate = 
                        AnnotationConfigUtils.attributesFor
                                        (importingClassMetadata, annType);
            if (candidate == null) {
                continue;
            }
            //默认是PROXY
            Object mode = candidate.get("mode");
            //默认是false
            Object proxyTargetClass = candidate.get("proxyTargetClass");
            if (mode != null &&
                proxyTargetClass != null && 
                AdviceMode.class == mode.getClass() &&
                Boolean.class == proxyTargetClass.getClass()) {
                candidateFound = true;
                if (mode == AdviceMode.PROXY) {
                    //注意:
                    //切面注册的是AnnotationAwareAspectJAutoProxyCreator
                    //事务会注入InfrastructureAdvisorAutoProxyCreator
                    //如果事务和切面同时存在使用AnnotationAwareAspectJAutoProxyCreator
                    //主要就是判断是否存在名为internalAutoProxyCreator的bean
                    //如果不存在就注入AnnotationAwareAspectJAutoProxyCreator
                    //如果存在就判断当前注入的bean权重和已经注入的bean的权重
                    //如果当前注入的bean的权重大于已经注入的bean的权重
                    //则注入当前bean
                    AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                    if ((Boolean) proxyTargetClass) {
                        AopConfigUtils
                            .forceAutoProxyCreatorToUseClassProxying(registry);
                        return;
                    }
                }
            }
        }
    }
}
	@Nullable
	public static BeanDefinition registerAutoProxyCreatorIfNecessary
									(BeanDefinitionRegistry registry) {
		return registerAutoProxyCreatorIfNecessary(registry, null);
	}
@Nullable
	public static BeanDefinition registerAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		//注意这里写死的是InfrastructureAdvisorAutoProxyCreator
		return registerOrEscalateApcAsRequired
            (InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}

注册InfrastructureAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator继承SmartInstantiationAwareBeanPostProcessor也就是一个BeanPostProcessor。

继承了AbstractAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator重写了BeanPostProcessor的postProcessAfterInitialization。

postProcessAfterInitialization方法的主要的作用

1.在代理寻找候选Advisor时,会调用

InfrastructureAdvisorAutoProxyCreator#isEligibleAdvisorBean

判断是否是合适的AdvisorBean

主要是判断advisorName的角色是否是ROLE_INFRASTRUCTURE=2

this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);

其实就是为了让ProxyTransactionManagementConfiguration注册的BeanFactoryTransactionAttributeSourceAdvisor能被加入到候选的Advisor中。

//继续注入InfrastructureAdvisorAutoProxyCreator
//注意:切面注册的是AnnotationAwareAspectJAutoProxyCreator
//事务会注入InfrastructureAdvisorAutoProxyCreator
//如果事务和切面都有 注入得是AnnotationAwareAspectJAutoProxyCreator
//区别在于 2个类的isEligibleAdvisorBean方法
//AnnotationAwareAspectJAutoProxyCreator是直接返回true
//InfrastructureAdvisorAutoProxyCreator是判断了
this.beanFactory.getBeanDefinition(beanName).getRole() == 					
                                 BeanDefinition.ROLE_INFRASTRUCTURE

2.生成代理类

public class InfrastructureAdvisorAutoProxyCreator extends      
                                    AbstractAdvisorAutoProxyCreator {
    @Nullable
    private ConfigurableListableBeanFactory beanFactory;
​
    @Override
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.initBeanFactory(beanFactory);
        this.beanFactory = beanFactory;
    }
​
    /***
     * 在做代理时 判断是否是合适的候选Advisor类
     * AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
     */
    @Override
    protected boolean isEligibleAdvisorBean(String beanName) {
        /****
    这个条件是寻找AVISOR的Role是 ROLE_INFRASTRUCTURE
    比如 BeanFactoryTransactionAttributeSourceAdvisor
    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {}
         */
        return (this.beanFactory != null && 
                this.beanFactory
                    .containsBeanDefinition(beanName) &&
                //判断getRole() == BeanDefinition.ROLE_INFRASTRUCTURE
                this.beanFactory
                        .getBeanDefinition(beanName)
                            .getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
    }
​
}
​

导入:ProxyTransactionManagementConfiguration

@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends        
                        AbstractTransactionManagementConfiguration {
​
    /**
     使用@Bean注入事务增强器(Advisor)
     在事务类创建的时候,被AutoProxyRegistrar导入的组件
     InfrastructureAdvisorAutoProxyCreator拦截,
     InfrastructureAdvisorAutoProxyCreator拦截的逻辑就是增强事务类的事务方法
     而BeanFactoryTransactionAttributeSourceAdvisor作为增强器。
     需要把类中所有的方法与需要增强的方法(这里是指被@Transactional标记的方法)进行匹配
     匹配成功的增强器
     最后会转成拦截器(MethodInterceptor,就是下面的TransactionInterceptor)
     然后与目标方法一起在拦截器链中被执行,达到方法增强的效果;
​
     BeanFactoryTransactionAttributeSourceAdvisor的继承关系如下:
     --Advisor 顶级接口
     --PointcutAdvisor
     --AbstractPointcutAdvisor
     --AbstractBeanFactoryPointcutAdvisor
     --BeanFactoryTransactionAttributeSourceAdvisor
     
​
      AOP中AspectJPointcutAdvisor的继承关系如下,与AbstractPointcutAdvisor一样,都实现了         --Advisor
         --PointcutAdvisor
           --AspectJPointcutAdvisor
     */
    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        //主要看它的getPointCut方法
        //会创建1个methodMatcher
        //根据methodMatcher判断方法是否需要匹配被应用事务
        BeanFactoryTransactionAttributeSourceAdvisor advisor
                         = new BeanFactoryTransactionAttributeSourceAdvisor();
        //注入解析器
        //判断是否canApply的时候会用上
        //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
        advisor.setTransactionAttributeSource(transactionAttributeSource());
        //transactionInterceptor()返回1个transactionInterceptor
        //有2个用处:
        //1.在getInterceptorsAndDynamicInterceptionAdvice方法
        //将BeanFactoryTransactionAttributeSourceAdvisor转换为对应的interceptor
        
        //2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器
        //具体看transactionInteceptor的invoke方法
        advisor.setAdvice(transactionInterceptor());
        if (this.enableTx != null) {
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
        }
        return advisor;
    }
    
 
    /***
     使用@Bean注入 AnnotationTransactionAttributeSource
     主要注入2个@Transactional注解解析器
     this.annotationParsers.add(new SpringTransactionAnnotationParser());
     this.annotationParsers.add(new JtaTransactionAnnotationParser());
     */
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionAttributeSource transactionAttributeSource() {
        /***
         true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧?
         public AnnotationTransactionAttributeSource() {
            this(true);
         }
         */
        return new AnnotationTransactionAttributeSource();
    }
    
    /***
    public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        if (jta12Present || ejb3Present) {
            this.annotationParsers = new LinkedHashSet<>(4);
            this.annotationParsers.add(new SpringTransactionAnnotationParser());
            if (jta12Present) {
                this.annotationParsers.add(new JtaTransactionAnnotationParser());
            }
            if (ejb3Present) {
                this.annotationParsers.add
                            (new Ejb3TransactionAnnotationParser());
            }
        }else {
            this.annotationParsers 
                        = Collections.singleton
                                (new SpringTransactionAnnotationParser());
        }
    }
***/
    /**
     被@Transactional标记的事务方法的拦截器,实际是一个MethodInterceptor
     保存了事务属性信息,事务管理器
     在目标方法执行的时候;执行拦截器链
     */
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        //执行代理类的invoke方法的时候会用上
        //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解是否存在
        interceptor.setTransactionAttributeSource(transactionAttributeSource());
        if (this.txManager != null) {
            //设置事务管理器
            interceptor.setTransactionManager(this.txManager);
        }
        return interceptor;
    }
​
}

ProxyTransactionManagementConfiguration是一个配置类。

主要有三个方法,每个方法作用如下:

注入BeanFactoryTransactionAttributeSourceAdvisor

向IOC容器中导入事务增强器:BeanFactoryTransactionAttributeSourceAdvisor

在bean被代理做事务增强时。这个advisor会被选为候选advisor用于增强事务。注意是候选

BeanFactoryTransactionAttributeSourceAdvisor相当于是1个中介。

把TransactionAttributeSource和TransactionInterceptor 关联起来。

TransactionAttributeSource主要用于获取解析器解析@Transaction注解

TransactionInterceptor主要用于方法拦截执行拦截器链。

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
​
    @Nullable
    private TransactionAttributeSource transactionAttributeSource;
    
    //注意pointcut是 TransactionAttributeSourcePointcut 间接继承了MethodMatcher
    //在判断是否是可用的advisor时会用到这个TransactionAttributeSourcePointcut
    //主要是调用matches方法
    //TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut
    //StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut 
    //StaticMethodMatcher implements MethodMatcher
     //会创建1个methodMatcher
     //根据methodMatcher判断方法是否需要匹配被应用事务
    private final TransactionAttributeSourcePointcut pointcut 
                                    = new TransactionAttributeSourcePointcut() {
        @Override
        @Nullable
        protected TransactionAttributeSource getTransactionAttributeSource() {
            return transactionAttributeSource;
        }
    };
    
    public void setTransactionAttributeSource
                        (TransactionAttributeSource transactionAttributeSource) {
        this.transactionAttributeSource = transactionAttributeSource;
    }
    
    public void setClassFilter(ClassFilter classFilter) {
        this.pointcut.setClassFilter(classFilter);
    }
​
    @Override
    public Pointcut getPointcut() {
        return this.pointcut;
    }
}
​

根据methodMatcher判断方法是否需要匹配被应用事务

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
​
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
        PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
        PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
            return false;
        }
        
        TransactionAttributeSource tas = getTransactionAttributeSource();
        
       return 
          (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
    }
 
    @Nullable
    protected abstract TransactionAttributeSource getTransactionAttributeSource();
}

注入AnnotationTransactionAttributeSource

向IOC容器中导入事务注解@Transactional的解析器AnnotationTransactionAttributeSource

主要是注入了2个@Transactional的解析器,解析@Transactional的属性值。

this.annotationParsers.add(new SpringTransactionAnnotationParser()); this.annotationParsers.add(new JtaTransactionAnnotationParser());

这2个解析器在2个地方会被用到:

1.判断候选advisor(候选的advisor指的是所有的advisor),是否可以被应用需要调用canApply方法判断

2.在使用jdk代理时,调用代理的invoke方法,会使用这2个解析器去解析@Transactional。然后再去匹配是否需要应用BeanFactoryTransactionAttributeSourceAdvisor。

/***
     使用@Bean注入 AnnotationTransactionAttributeSource
     主要注入2个@Transactional注解解析器
     this.annotationParsers.add(new SpringTransactionAnnotationParser());
     this.annotationParsers.add(new JtaTransactionAnnotationParser());
     */
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionAttributeSource transactionAttributeSource() {
        /***
         true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧?
         public AnnotationTransactionAttributeSource() {
            this(true);
         }
         */
        return new AnnotationTransactionAttributeSource();
    }
​
    
    public AnnotationTransactionAttributeSource() {
        this(true);
    }
​
​
​
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        if (jta12Present || ejb3Present) {
            this.annotationParsers = new LinkedHashSet<>(4);
            this.annotationParsers.add(new SpringTransactionAnnotationParser());
            if (jta12Present) {
                this.annotationParsers.add(new JtaTransactionAnnotationParser());
            }
            if (ejb3Present) {
                this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
            }
        }
        else {
            this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
        }
    }

注入TransactionInterceptor

BeanFactoryTransactionAttributeSourceAdvisor方法中设置了 advisor.setAdvice(transactionInterceptor());

BeanFactoryTransactionAttributeSourceAdvisor被加入拦截器链,底层使用的还是TransactionInterceptor。

TransactionInterceptor中设置了事务管理器TransactionManager

TransactionManager中实现了方法开启事务 提交事务 异常回滚事务等。

        /**
         被@Transactional标记的事务方法的拦截器,实际是一个MethodInterceptor
         保存了事务属性信息,事务管理器
         在目标方法执行的时候;执行拦截器链
         *///transactionInterceptor()返回1个transactionInterceptor
        //有2个用处:
        //1.获取调用链时调用getInterceptorsAndDynamicInterceptionAdvice方法
        //将BeanFactoryTransactionAttributeSourceAdvisor
        //转换为transactionInterceptor
        //因为在BeanFactoryTransactionAttributeSourceAdvisor的注入方法中已经设置了
        //advisor.setAdvice(transactionInterceptor());
        
        //2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器
        //具体看transactionInteceptor的invoke方法
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        //执行代理类的invoke方法的时候会用上
        //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解是否存在
        interceptor.setTransactionAttributeSource(transactionAttributeSource());
        if (this.txManager != null) {
            //设置事务管理器
            interceptor.setTransactionManager(this.txManager);
        }
        return interceptor;
    }

向IOC容器中导入事务方法拦截器TransactionInterceptor

在使用jdk代理时,调用代理的invoke方法,会取出TransactionInterceptor的TransactionManager做事务增强

    @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);
    }
@Nullable
    protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
            final InvocationCallback invocation) throws Throwable {
​
        // If the transaction attribute is null, the method is non-transactional.
        TransactionAttributeSource tas = getTransactionAttributeSource();
        final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
        //获取设置的事务管理器
        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;
            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;
        }
​
        else {
            Object result;
            final ThrowableHolder throwableHolder = new ThrowableHolder();
​
            // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
            try {
                result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
                    TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
                    try {
                        return invocation.proceedWithInvocation();
                    }
                    catch (Throwable ex) {
                        if (txAttr.rollbackOn(ex)) {
                            // A RuntimeException: will lead to a rollback.
                            if (ex instanceof RuntimeException) {
                                throw (RuntimeException) ex;
                            }
                            else {
                                throw new ThrowableHolderException(ex);
                            }
                        }
                        else {
                            // A normal return value: will lead to a commit.
                            throwableHolder.throwable = ex;
                            return null;
                        }
                    }
                    finally {
                        cleanupTransactionInfo(txInfo);
                    }
                });
            }
            catch (ThrowableHolderException ex) {
                throw ex.getCause();
            }
            catch (TransactionSystemException ex2) {
                if (throwableHolder.throwable != null) {
                    logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                    ex2.initApplicationException(throwableHolder.throwable);
                }
                throw ex2;
            }
            catch (Throwable ex2) {
                if (throwableHolder.throwable != null) {
                    logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                }
                throw ex2;
            }
​
            // Check result state: It might indicate a Throwable to rethrow.
            if (throwableHolder.throwable != null) {
                throw throwableHolder.throwable;
            }
            return result;
        }
    }