当前位置 博文首页 > 文章内容

    Spring声明式事务注解之@EnableTransactionManagement解析

    作者:shunshunshun18 栏目:未分类 时间:2021-08-09 14:45:33

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    Spring声明式事务注解之@EnableTransactionManagement

    1. 说明

    @EnableTransactionManagement声明在主配置类上,表示开启声明式事务,其原理是通过@Import导入TransactionManagementConfigurationSelector组件,然后又通过TransactionManagementConfigurationSelector导入组件AutoProxyRegistrar和ProxyTransactionManagementConfiguration;

    2. 原理分析

    @EnableTransactionManagement代码实现如下:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    // 通过@Import导入TransactionManagementConfigurationSelector组件
    @Import(TransactionManagementConfigurationSelector.class) 
    public @interface EnableTransactionManagement { 
     boolean proxyTargetClass() default false; 
     AdviceMode mode() default AdviceMode.PROXY; 
     int order() default Ordered.LOWEST_PRECEDENCE;
    }

    @EnableTransactionManagement通过@Import导入TransactionManagementConfigurationSelector;

    TransactionManagementConfigurationSelector的实现如下:

    public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
     
     /**
      * {@inheritDoc}
      * @return {@link ProxyTransactionManagementConfiguration} or
      * {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
      * {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
      */
     @Override
     protected String[] selectImports(AdviceMode adviceMode) {
      switch (adviceMode) {
       case PROXY:
        // 根据@EnableTransactionManagement的固定值PROXY,这里会导入AutoProxyRegistrar组件和ProxyTransactionManagementConfiguration组件
        return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
       case ASPECTJ:
        return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
       default:
        return null;
      }
     } 
    }

    所以TransactionManagementConfigurationSelector又导入了组件AutoProxyRegistrar和ProxyTransactionManagementConfiguration;

    3. AutoProxyRegistrar分析

    3.1 AutoProxyRegistrar继承关系

    InfrastructureAdvisorAutoProxyCreator
        --AbstractAdvisorAutoProxyCreator
            --AbstractAdvisorAutoProxyCreator
                --ProxyProcessorSupport
                --SmartInstantiationAwareBeanPostProcessor  // 跟AOP是原理是一样的
                    --InstantiationAwareBeanPostProcessor
                        --BeanPostProcessor
                --BeanFactoryAware

    3.2 AutoProxyRegistrar的所用

    AutoProxyRegistrar的作用跟AOP中的AnnotationAwareAspectJAutoProxyCreator是一样的,利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;InfrastructureAdvisorAutoProxyCreator继承SmartInstantiationAwareBeanPostProcessor,跟AOP的原理是一样的,也是通过@Transactional作为方法拦截的标记,把有事务管理的类作为目标类,生成代理对象,然后增强@Transactional标记的方法,在使用目标方法的时候,从IOC容器中获取的其实是被增强的代理类,且事务方法会被代理,跟AOP原理一样的;

    4. ProxyTransactionManagementConfiguration分析

    ProxyTransactionManagementConfiguration是一个配置类,想IOC容器中导入事务增强器(BeanFactoryTransactionAttributeSourceAdvisor),事务注解@Transactional的解析器(AnnotationTransactionAttributeSource)和事务方法拦截器(TransactionInterceptor);

    package org.springframework.transaction.annotation; 
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Role;
    import org.springframework.transaction.config.TransactionManagementConfigUtils;
    import org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor;
    import org.springframework.transaction.interceptor.TransactionAttributeSource;
    import org.springframework.transaction.interceptor.TransactionInterceptor;
     
    @Configuration
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
     
    	
    	/** 
    		事务增强器(Advisor),在事务类创建的时候,被AutoProxyRegistrar导入的组件InfrastructureAdvisorAutoProxyCreator拦截,
    		InfrastructureAdvisorAutoProxyCreator拦截的逻就是增强事务类的事务方法,	而BeanFactoryTransactionAttributeSourceAdvisor作为增强器,
    		与需要增强的方法(这里是指被@Transactional标记的方法)进行匹配,匹配成功的增强器,最后转成拦截器(MethodInterceptor,
    		就是下面的TransactionInterceptor),然后与目标方法一起在拦截器链中被执行,达到方法增强的效果;
    		
    		
    		BeanFactoryTransactionAttributeSourceAdvisor的继承关系如下:
    		
    		BeanFactoryTransactionAttributeSourceAdvisor
    			--AbstractBeanFactoryPointcutAdvisor
    				--AbstractPointcutAdvisor
    					--PointcutAdvisor
    						--Advisor
    		
    		AOP中AspectJPointcutAdvisor的继承关系如下,与AbstractPointcutAdvisor一样,都实现PointcutAdvisor
    				--AspectJPointcutAdvisor
    					--PointcutAdvisor
    						--Advisor
    	*/
    	@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注解的解析类;负责解析事务方法上@Transactional中的各个参数配置,解析的时机是在创建事务类之后被增强的时候,
    		匹配事务方法的时候一起被解析了
    		
    		AnnotationTransactionAttributeSource的继承关系如下:
    		
    		AnnotationTransactionAttributeSource
    			--AbstractFallbackTransactionAttributeSource
    				--TransactionAttributeSource
    		通过方法org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.getTransactionAttribute(Method, Class<?>)
    		解析出事务信息TransactionAttribute;
    		
    		AnnotationTransactionAttributeSource在方法findTransactionAttribute(Class<?>)中依赖于SpringTransactionAnnotationParser在解析事务类时,
    		绑定事务方法与增强器的时候进行@Transactional注解解析;
    		
    	*/
    	@Bean
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	public TransactionAttributeSource transactionAttributeSource() {
    		return new AnnotationTransactionAttributeSource();
    	}
     
    	/**
    		被@Transactional标记的事务方法的拦截器,实际是一个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;
    	}
    }

    在SpringTransactionAnnotationParser中parseTransactionAnnotation方法来解析@Transactional中的各个参数,其具体代码如下:

    protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
    	RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
    	Propagation propagation = attributes.getEnum("propagation");
    	rbta.setPropagationBehavior(propagation.value());
    	Isolation isolation = attributes.getEnum("isolation");
    	rbta.setIsolationLevel(isolation.value());
    	rbta.setTimeout(attributes.getNumber("timeout").intValue());
    	rbta.setReadOnly(attributes.getBoolean("readOnly"));
    	rbta.setQualifier(attributes.getString("value"));
    	ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<RollbackRuleAttribute>();
    	Class<?>[] rbf = attributes.getClassArray("rollbackFor");
    	for (Class<?> rbRule : rbf) {
    		RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
    		rollBackRules.add(rule);
    	}
    	String[] rbfc = attributes.getStringArray("rollbackForClassName");
    	for (String rbRule : rbfc) {
    		RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
    		rollBackRules.add(rule);
    	}
    	Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
    	for (Class<?> rbRule : nrbf) {
    		NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
    		rollBackRules.add(rule);
    	}
    	String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
    	for (String rbRule : nrbfc) {
    		NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
    		rollBackRules.add(rule);
    	}
    	rbta.getRollbackRules().addAll(rollBackRules);
    	return rbta;
    }

    spring 事务 @EnableTransactionManagement原理

    @EnableXXX原理:注解上有个XXXRegistrar,或通过XXXSelector引入XXXRegistrar,XXXRegistrar实现了ImportBeanDefinitionRegistrar的registerBeanDefinitions方法,给容器注册XXXCreator。

    这个Creator实现了后置处理器,后置处理器在对象创建以后,包装对象,返回一个代理对象,代理对象执行方法利用拦截器链进行调用

    1)、@EnableTransactionManagement

    利用TransactionManagementConfigurationSelector给容器中会导入组件

    导入两个组件

    AutoProxyRegistrar
    ProxyTransactionManagementConfiguration
    

    2)、AutoProxyRegistrar:

    给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件;

    利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;

    3)、ProxyTransactionManagementConfiguration是个@Configuration

    1、给容器中注册事务增强器transactionAdvisor;

    1)、事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解

    2)、事务拦截器transactionInterceptor:

    TransactionInterceptor;保存了事务属性信息,事务管理器;

    TransactionInterceptor是一个 MethodInterceptor;

    在目标方法执行的时候;

    执行拦截器链;

    只有事务拦截器:

    1)、先获取事务相关的属性

    2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger 最终会从容器中按照类型获取一个PlatformTransactionManager;

    3)、执行目标方法

    如果异常,获取到事务管理器,利用事务管理回滚操作;

    如果正常,利用事务管理器,提交事务

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持IIS7站长之家博文。