@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
和ProxyTransactionManagementConfiguration
2個組件,源碼以下: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 的主要做用是將InfrastructureAdvisorAutoProxyCreator
後置處理器註冊到容器,註冊這個後置處理器和上一篇Spring AOP註冊AnnotationAwareAspectJAutoProxyCreator
後置處理器同樣,這裏就不在重複說明了。InfrastructureAdvisorAutoProxyCreator 他是實現了BeanPostProcessor 接口的後置處理器,因此全部 Bean 的初始化都會調用其 postProcessAfterInitialization
方法,這個方法的實現是在其父類AbstractAutoProxyCreator類中。編程
咱們經過ProxyTransactionManagementConfiguration
來註冊事務管理器組件,這個類自己也是一個配置類。在這個配置類中咱們將會註冊一下三個組件:app
TransactionInterceptor
和標籤解析器TransactionAttributeSource
上面咱們說了因此全部 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的核心流程:代理
- 單例Bean初始化完成後執行後置處理器
AbstractAutoProxyCreator#postProcessAfterInitialization
方法- 在容器中找
Advisor
類型的全部加強器名稱,這就會將與事務相關的加強器BeanFactoryTransactionAttributeSourceAdvisor
找出來- 根據加強器名稱獲取對應的實例,並生成攔截鏈
- 判斷代理類型
- 根據不一樣的代理類型和攔截鏈建立代理對象
前面AOP說過無論理是JdkDynamicAopProxy
仍是CglibAopProxy
代理,他們的執行最終都會去調用MethodInterceptor.invoke()
方法,而咱們事務對應的方法攔截器是TransactionInterceptor
類。也就是說咱們對事務的加強起始是在TransactionInterceptor
的invoke
方法中。源碼以下: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; } // 編程式事務 ... }
從上面咱們的源碼能夠看出,一個事務處理的標準流程:
createTransactionIfNecessary
建立一個事務invocation.proceedWithInvocation();
執行業務方法completeTransactionAfterThrowing(txInfo, ex);
若是遇到異常,事務回滾commitTransactionAfterReturning(txInfo);
若是沒有異常就提交事務在建立,回滾和提交事務方法中還有的不少對嵌套事務的邏輯,好比事務的傳遞性,事務回滾的條件判斷等,這裏就不說了,有興趣本身去跟下源碼。