Spring 源碼(七)Spring 事務

註冊後置處理器開啓對事務的支持

@EnableTransactionManagement

@EnableTransactionManagement註解的主要做用是開啓對事務的支持,源碼以下:java

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}

這裏最核心的是TransactionManagementConfigurationSelector類,這個類主要的做用是經過ImportSelector註冊了AutoProxyRegistrar ProxyTransactionManagementConfiguration2個組件,源碼以下:spring

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				// 註冊 InfrastructureAdvisorAutoProxyCreator 後置處理器和事務管理器組件
				return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
			default:
				return null;
		}
	}
}

AutoProxyRegistrar

AutoProxyRegistrar 的主要做用是將InfrastructureAdvisorAutoProxyCreator後置處理器註冊到容器,註冊這個後置處理器和上一篇Spring AOP註冊AnnotationAwareAspectJAutoProxyCreator後置處理器同樣,這裏就不在重複說明了。InfrastructureAdvisorAutoProxyCreator 他是實現了BeanPostProcessor 接口的後置處理器,因此全部 Bean 的初始化都會調用其 postProcessAfterInitialization 方法,這個方法的實現是在其父類AbstractAutoProxyCreator類中。編程

ProxyTransactionManagementConfiguration

咱們經過ProxyTransactionManagementConfiguration來註冊事務管理器組件,這個類自己也是一個配置類。在這個配置類中咱們將會註冊一下三個組件:app

  • BeanFactoryTransactionAttributeSourceAdvisor:事務加強器,包含了切面組件 TransactionInterceptor和標籤解析器TransactionAttributeSource
  • TransactionAttributeSource:@Transaction註解標籤解析器
  • TransactionInterceptor:保存了事務屬性信息,事務管理器;它自己也是一個方法攔截器,在invoke方法中進行了事務的處理。

建立代理Bean

上面咱們說了因此全部 Bean 的初始化都會調用其 AbstractAutoProxyCreator#postProcessAfterInitialization 方法來完成Bean的加強,咱們跟進去能夠看到這段代碼:ide

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

能夠看到生代理對象是在wrapIfNecessary(bean, beanName, cacheKey);方法中完成的,源碼以下:post

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	
	// 若是存在建言那麼久建立代理類
	// 獲取攔截鏈
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		// 使用攔截鏈建立代理對象,對原有的Bean進行加強
		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}

找到攔截鏈的的核心方法是 BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans方法this

findAdvisorBeans:67, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:102, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
findEligibleAdvisors:88, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
wrapIfNecessary:346, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
postProcessAfterInitialization:298, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:423, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1638, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:555, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:543, AbstractApplicationContext (org.springframework.context.support)
<init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)

源碼以下:debug

public List<Advisor> findAdvisorBeans() {
	// Determine list of advisor bean names, if not cached already.
	String[] advisorNames = null;
	synchronized (this) {
		advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
			// 獲取全部加強器的名稱
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
	}
	if (advisorNames.length == 0) {
		return new LinkedList<Advisor>();
	}

	List<Advisor> advisors = new LinkedList<Advisor>();
	for (String name : advisorNames) {
		if (isEligibleBean(name)) {
			if (this.beanFactory.isCurrentlyInCreation(name)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping currently created advisor '" + name + "'");
				}
			}
			else {
				try {
					// 根據名稱加強器
					advisors.add(this.beanFactory.getBean(name, Advisor.class));
				}
				...
			}
		}
	}
	// 返回攔截鏈
	return advisors;
}

建立代理Bean的核心流程:代理

  1. 單例Bean初始化完成後執行後置處理器 AbstractAutoProxyCreator#postProcessAfterInitialization 方法
  2. 在容器中找Advisor類型的全部加強器名稱,這就會將與事務相關的加強器BeanFactoryTransactionAttributeSourceAdvisor找出來
  3. 根據加強器名稱獲取對應的實例,並生成攔截鏈
  4. 判斷代理類型
  5. 根據不一樣的代理類型和攔截鏈建立代理對象

執行業務方法進行攔截

前面AOP說過無論理是JdkDynamicAopProxy仍是CglibAopProxy代理,他們的執行最終都會去調用MethodInterceptor.invoke()方法,而咱們事務對應的方法攔截器是TransactionInterceptor類。也就是說咱們對事務的加強起始是在TransactionInterceptorinvoke方法中。源碼以下:code

@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
	...
	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 {

	// 獲取事務屬性
	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)) {
		// 建立事務
		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;
	}
	// 編程式事務
	...
}

從上面咱們的源碼能夠看出,一個事務處理的標準流程:

  1. createTransactionIfNecessary 建立一個事務
  2. invocation.proceedWithInvocation(); 執行業務方法
  3. completeTransactionAfterThrowing(txInfo, ex); 若是遇到異常,事務回滾
  4. commitTransactionAfterReturning(txInfo); 若是沒有異常就提交事務

在建立,回滾和提交事務方法中還有的不少對嵌套事務的邏輯,好比事務的傳遞性,事務回滾的條件判斷等,這裏就不說了,有興趣本身去跟下源碼。

相關文章
相關標籤/搜索