欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring声明式事务原理解析

程序员文章站 2022-03-23 22:11:47
前言学习雷老师的Spring注解版所做的笔记若有不当之处,请您指出,您的指点是我的荣幸温馨提示:本文含有较多代码,已经做了一些省略,请尽量关注中文注释的地方事务要使用事务就离不开:@EnableTransactionManagement注解所以本文就@EnableTransactionManagement做了什么进行探究。@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented//可以看到@Enabl...

1,前言

学习雷老师的Spring注解版所做的笔记

若有不当之处,请您指出,您的指点是我的荣幸

温馨提示:本文含有较多代码,已经做了一些省略,请尽量关注中文注释的地方

2,事务

要使用事务就离不开:@EnableTransactionManagement注解
所以本文就@EnableTransactionManagement做了什么进行探究。

2.1,EnableTransactionManagement源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//可以看到@EnableTransactionManagement给容器注入了一个TransactionManagementConfigurationSelector
//TransactionManagementConfigurationSelector是ImportSelector的子类,负责导入一些组件
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	//记住这两个属性
	boolean proxyTargetClass() default false;
	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}
//接下来就看看TransactionManagementConfigurationSelector做了什么

2.2,TransactionManagementConfigurationSelector

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    public TransactionManagementConfigurationSelector() {
    }

    protected String[] selectImports(AdviceMode adviceMode) {
        switch(adviceMode) {
			//而EnableTransactionManagement中又设置了AdviceMode.PROXY
			//换句话说,就是这个EnableTransactionManagement组件负责给容器中添加两个组件:
			//AutoProxyRegistrar,ProxyTransactionManagementConfiguration        
            case PROXY:
                return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
            case ASPECTJ:
                return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
            default:
                return null;
        }
    }
}

//接下来的任务就变成,研究TransactionManagementConfigurationSelector给容器导入的这两个组件做了什么

2.3,AutoProxyRegistrar

2.3.1,AutoProxyRegistrar源码

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	private final Log logger = LogFactory.getLog(getClass());

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        	
        	......	
        
        
			if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
					Boolean.class == proxyTargetClass.getClass()) {
				candidateFound = true;
                
                //会进到这一行
				if (mode == AdviceMode.PROXY) {
                    
                    //注册一个AutoProxyCreator
                    //接下来看一下registerAutoProxyCreatorIfNecessary做了什么操作
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					
					......
					
				}
			}
		}
		if (!candidateFound) {
			
            ......
            
        }
	}
}

2.3.2,registerAutoProxyCreatorIfNecessary

//继续点进去,会来到AopConfigUtils
public abstract class AopConfigUtils {

    ......


	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
		return registerAutoProxyCreatorIfNecessary(registry, null);
	}

	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        
        //可以看到目的是为了注册InfrastructureAdvisorAutoProxyCreator
        //基本的增强器自动代理创建器
        //而且通过分析它的继承树,可以发现它也是个后置处理器【SmartInstantiationAwareBeanPostProcessor】
		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}
    
    ......
        
}
//那么就可以得出:AutoProxyRegistrar是为了给容器中导入一个InfrastructureAdvisorAutoProxyCreator
//而且InfrastructureAdvisorAutoProxyCreator是利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(这一点与AOP类似)
//AutoProxyRegistrar就研究到这里,接下来研究另一个组件

2.4,ProxyTransactionManagementConfiguration

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    public ProxyTransactionManagementConfiguration() {
    }

    @Bean(
        name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
    )
    @Role(2)
    //这里是给容器中导入一个事务增强器!
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        
        //这里是设置事务属性,调用下面的方法transactionAttributeSource()
        advisor.setTransactionAttributeSource(this.transactionAttributeSource());
        
        //设置一个事务拦截器
        //调用下面的方法transactionInterceptor()
        advisor.setAdvice(this.transactionInterceptor());
        advisor.setOrder((Integer)this.enableTx.getNumber("order"));
        return advisor;
    }

    @Bean
    @Role(2)
    //这里又new了一个AnnotationTransactionAttributeSource
    //点进去查看
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }
    
    
    @Bean
    @Role(2)
    //设置事务拦截器
    public TransactionInterceptor transactionInterceptor() {
        //点进去看看TransactionInterceptor这个类
        TransactionInterceptor interceptor = new TransactionInterceptor();
        //设置事务属性
        interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
        if (this.txManager != null) {
            //设置TransactionManager
            interceptor.setTransactionManager(this.txManager);
        }
		//而这个interceptor实际上是一个MethodInterceptor--方法拦截器
        //会在执行目标方法的时候,执行拦截器链(讲AOP原理的文章有详细记录)
        //而这个拦截器链只有一个事务拦截器--interceptor
        return interceptor;
    }
    
}

2.4.1,AnnotationTransactionAttributeSource

//AnnotationTransactionAttributeSource
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable {

    
    ......
        

    public AnnotationTransactionAttributeSource() {
        this(true);
    }

    //解析事务注解信息
    public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        this.annotationParsers = new LinkedHashSet(2);
        
        //这个是事务注解的解析器,用来解析Spring事务注解
        this.annotationParsers.add(new SpringTransactionAnnotationParser());
        //Jta事务注解的解析器
        if (jta12Present) {
            this.annotationParsers.add(new JtaTransactionAnnotationParser());
        }
		//Ejb3事务注解的解析器
        if (ejb3Present) {
            this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
        }

    }
    
    ......
        
}

//解析完事务属性之后,就继续研究一下事务拦截器
//点进TransactionInterceptor这个类查看

2.4.2,TransactionInterceptor

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

    
    ......
        

    public Object invoke(final MethodInvocation invocation) throws Throwable {
        Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
        
        //重点关注invokeWithinTransaction,看看这个拦截器在目标方法执行前后做了什么
        return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
            public Object proceedWithInvocation() throws Throwable {
                return invocation.proceed();
            }
        });
    }

    
    ......
   
       
}

接下来就是关注invokeWithinTransaction() 这个方法做了什么

//invokeWithinTransaction
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
    throws Throwable {

    // If the transaction attribute is null, the method is non-transactional.
    //先获取事务相关的属性
    final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);

    //再获取平台的事务管理器
    //如果事先没有指定任何的TransactionManager,就会从容器中按照类型获取一个PlatformTransactionManager
    final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

    if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {

        //如果是必需的就创建一个Transaction,也就是开启事务
        TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

        Object retVal = null;
        try {
            //事务方法执行
            retVal = invocation.proceedWithInvocation();
        }

        catch (Throwable ex) {

            //如果出现异常的话,就获取事务管理器,利用事务管理器回滚操作,
            //也就是说,回滚是由事务管理器来操作的
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        }
        finally {
            cleanupTransactionInfo(txInfo);
        }
        //如果正常,利用事务管理器提交事务
        commitTransactionAfterReturning(txInfo);
        return retVal;
    }

    else {
        
        ......
        
    }
}

注:若有兴趣可以查看–有关AOP的文章

本文地址:https://blog.csdn.net/weixin_41043607/article/details/107692442

相关标签: Spring