Spring源码阅读(七)-事务

一、InfrastructureAdvisorAutoProxyCreator

1、它是通过@EnableTransactionManagement、< tx:annotation-driven /> 注入的,下面以@EnableTransactionManagement注解的方式为例,看下是如何注入的。
TransactionManagementConfigurationSelector#selectImports()

protected String[] selectImports(AdviceMode adviceMode) {
	switch (adviceMode) {
		case PROXY:
			return new String[] {AutoProxyRegistrar.class.getName(),
					ProxyTransactionManagementConfiguration.class.getName()};
		case ASPECTJ:
			return new String[] {
					TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
		default:
			return null;
	}
}

默认进入PROXY分支,注入两个类:AutoProxyRegistrar、ProxyTransactionManagementConfiguration。AutoProxyRegistrar注入了InfrastructureAdvisorAutoProxyCreator,而ProxyTransactionManagementConfiguration则注入了AnnotationTransactionAttributeSource、TransactionInterceptor、BeanFactoryTransactionAttributeSourceAdvisor这三个类,他们支撑了整个事务的功能。
仔细回忆一下AOP的源码,BeanFactoryTransactionAttributeSourceAdvisor,TransactionInterceptor不就是AOP的增强器和拦截器链吗?只不过是Spring事务帮我们直接定义好了,不需要再创建而已,所以说AOP是Spring事务的基础!

回顾一下AOP的原理,AOP中有一个 Advisor 存放在代理类中,而Advisor中有advise与pointcut信息,每次执行被代理类的方法时都会执行代理类的invoke(如果是JDK代理)方法,而invoke方法会根据advisor中的pointcut动态匹配这个方法需要执行的advise链,遍历执行advise链,从而达到AOP切面编程的目的。

通过源码和类图可以直观的看到三者之间的关系:

public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		// 将pointcut注入进advisor中
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		// 将advice注入进advisor中
		advisor.setAdvice(transactionInterceptor());
		advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}

	@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;
	}
}

在这里插入图片描述

2、看下它的继承关系:
在这里插入图片描述
3、由上图可知,InfrastructureAdvisorAutoProxyCreator分别继承了BeanPostProcessor、InstantiationAwareBeanPostProcessor,所以AnnotationAwareAspectJAutoProxyCreator会有postProcessAfterInitialization() 和 postProcessBeforeInstantiation() 方法,接下来的分析重点和AOP几乎一模一样的,可以参考《Spring源码阅读-AOP》 这篇文章的分析过程。

二、Spring事务的调用-TransactionInterceptor

1、TransactionInterceptor#invoke()方法是Spring事务最终调用的地方,看下源码:

public Object invoke(final 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, new InvocationCallback() {
		@Override
		public Object proceedWithInvocation() throws Throwable {
			return invocation.proceed();
		}
	});
}
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);
	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 {
			// spring事务是个环绕通知,在此执行目标方法
			// 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;
	}
	
	*******
	
}

由上述代码和注释可知spring事务是个环绕通知!

2、另外如下调用链是Spring事务传播行为相关的代码,可以在此方法中进行查看分析。

TransactionAspectSupport#createTransactionIfNecessary
	->AbstractPlatformTransactionManager#getTransaction
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值