Spring原始碼分析筆記--事務管理
核心類
InfrastructureAdvisorAutoProxyCreator
本質是一個後置處理器,和AOP的後置處理器類似,但比AOP的使用級別低。當開啟AOP代理模式後,優先使用AOP的後置處理器。
AopConfigUtils:
/** * The bean name of the internally managed auto-proxy creator. */ //和AOP一樣都向容器注入以此為name的後置處理器,進行代理類的建立 public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";/** * Stores the auto proxy creator classes in escalation order. */ //按升級的順序儲存進行代理類建立的後置處理器 private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>(); /** * Setup the escalation list. */ //代理建立類後置處理器升級列表,下標越大等級越高 static { APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class); APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class); APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class); }
原始碼跟蹤
檢視註解@EnableTransactionManagement原始碼,通過@Import匯入TransactionManagementConfigurationSelector類,在類的重寫方法中可以看到向容器注入了兩個類AutoProxyRegistrar、ProxyTransactionManagementConfiguration
AutoProxyRegistrar
用於向容器中註冊事務管理用的後置處理器
==》org.springframework.context.annotation.AutoProxyRegistrar#registerBeanDefinitions
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
==》org.springframework.aop.config.AopConfigUtils#registerAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
==》org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired
//此類下檢查容器中是否有name為:"org.springframework.aop.config.internalAutoProxyCreator"的後置處理器bean,如果沒有則註冊,如果有則比較等級大小,若是等級大則對原beanDefination升級。例如:如果啟用了AOP則不用升級
ProxyTransactionManagementConfiguration
配置事務管理所需的管理器、引數等
@Configuration public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration { //類似AOP,這裡建立了一個用於事務Advisor的Bean @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(..)中的引數 @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource(); } //封裝事務用的advice為Interceptor,並關聯上了事務管理器 // TransactionInterceptor與AOP的Interceptor一樣都繼承自MethodInterceptor //事務管理器主要用來控制事務,commit、rollback等 @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; } }
執行時原始碼
執行時原理同AOP,對添加了@Transactional註解的類做代理,對被代理類的方法進行增強處理,執行一個攔截器鏈。跟蹤進去可以發現Interceptor chain中多了一個TransactionIntercepor。通過此Interceptor在方法前開啟事務,在方法後commit或rollback。
TransactionInterceptor
==》org.springframework.transaction.interceptor.TransactionInterceptor#invoke
==》 org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
// 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 { // 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; }
流程梳理
1、 建立後置處理器InfrastructureAdvisorAutoProxyCreator
2、 建立TransactionInterceptor,加入interceptor chain。
3、 對指定後置處理器為InfrastructureAdvisorAutoProxyCreator的bean使用TransactionInterceptor進行事務處理。