spring事务管理 TransactionProxyFactoryBean源码分析
J2EE,當然離不開事務,事務又當然少不了Spring聲明式事務。spring聲明式事務,很多碼農門,應該和筆者一樣,停留在使用上,及僅僅了解點原理。如:Spring事務管理原理“代理+AOP”,再深入了解就不太清楚了。一直對聲明式事務實現特別感興趣,今天抽時間,剖析一下下。
1.準備
?BeanFactory,及對象生成周期
?AOP代理對象生成過程
1.1.BeanFactory 及生命周期
| Factory class name | 作用 |
| ListableBeanFactory | 枚舉所有的bean實例 |
| HierarchicalBeanFactory | 維護工廠父子關系 |
| ConfigurableBeanFactory | 配置BeanFactory |
| AutowireCapableBeanFactory | 維護ean屬性注入和依賴關系維護 |
| ConfigurableListableBeanFactory | BeanFacotry配置清單,指定忽略接口 |
| SingletonBeanRegistry | 維護單例關系 |
| FactoryBeanRegistrySupport | 針對FactoryBean,維護單例關系 |
| AbstractBeanFactory | ConfigurableBeanFactory SPI. |
| AbstractAutowireCapableBeanFactory | 提供create bean默認實現 |
| DefaultListableBeanFactory | 一個基于bean定義對象的完整的bean工廠;默認 |
總之,spring容器中涉及的對象,都是通過上面的BeanFactory樹結構中創建而來。生成的代理對象也是如此。
1.2 周期lifecycle
?1. BeanNameAware's setBeanName
?2. BeanClassLoaderAware's setBeanClassLoader
?3. BeanFactoryAware's setBeanFactory
?4. ResourceLoaderAware's setResourceLoader (only applicable when running in an application context)
?5. ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context)
?6. MessageSourceAware's setMessageSource (only applicable when running in an application context)
?7. ApplicationContextAware's setApplicationContext (only applicable when running in an application context)
?8. ServletContextAware's setServletContext (only applicable when running in a web application context)
?9. postProcessBeforeInitialization methods of BeanPostProcessors
?10. InitializingBean's afterPropertiesSet
?11. a custom init-method definition
?12. postProcessAfterInitialization methods of BeanPostProcessors
beanfactory shutdown
?1. DisposableBean's destroy
?2. a custom destroy-method definition
其中生成代理對象,僅僅是上面(1-12)步驟中的一步而已。
1.2 AOP 代理對象生成
1.2.1?TargetClassAware
用于將目標類暴露在代理后面的最小界面。
1.2.2?Advised
AOP代理配置接口
public?interface?Advised?extends?TargetClassAware?{/**是否凍結了“Advised”配置,在這種情況下,無法進行任何建議更改。*/boolean?isFrozen();/**?代理完整的目標類而不是指定的接口?*/boolean?isProxyTargetClass();/**返回由AOP代理代理的接口??*/Class<?>[]?getProxiedInterfaces();/**確定給定的接口是否被代理。?*/boolean?isInterfaceProxied(Class<?>?intf);/**?更改此Advised對象使用的TargetSource。?*/void?setTargetSource(TargetSource?targetSource);TargetSource?getTargetSource();/**是否可以被AOP框架作為ThreadLocal暴露,通過AopContext。?*/void?setExposeProxy(boolean?exposeProxy);boolean?isExposeProxy();/**設置此代理配置是否經過預篩選,以便它僅包含適用的advisors?(與此代理的目標類匹配)。?*/void?setPreFiltered(boolean?preFiltered);boolean?isPreFiltered();/**返回適用于此代理的Advisor。*/Advisor[]?getAdvisors();void?addAdvisor(Advisor?advisor)?throws?AopConfigException;void?addAdvisor(int?pos,?Advisor?advisor)?throws?AopConfigException;boolean?removeAdvisor(Advisor?advisor);void?removeAdvisor(int?index)?throws?AopConfigException;int?indexOf(Advisor?advisor);boolean?replaceAdvisor(Advisor?a,?Advisor?b)?throws?AopConfigException;/**將給定的AOP?advice?添加到advice(interceptor)鏈的尾部。這將包含在一個DefaultPointcutAdvisor中,該切點總是適用,*/void?addAdvice(Advice?advice)?throws?AopConfigException;void?addAdvice(int?pos,?Advice?advice)?throws?AopConfigException;boolean?removeAdvice(Advice?advice);int?indexOf(Advice?advice);String?toProxyConfigString(); }1.2.3?AdvisedSupport
AOP代理配置管理器的基類
public?class?AdvisedSupport?extends?ProxyConfig?implements?Advised?{/**?Package-protected?to?allow?direct?access?for?efficiency?*/TargetSource?targetSource?=?EMPTY_TARGET_SOURCE;/**?Advisors是否已針對特定目標類過濾?*/private?boolean?preFiltered?=?false;/**?The?AdvisorChainFactory?to?use?*/AdvisorChainFactory?advisorChainFactory?=?new?DefaultAdvisorChainFactory();/**?Cache?with?Method?as?key?and?advisor?chain?List?as?value?*/private?transient?Map<MethodCacheKey,?List<Object>>?methodCache;/***?接口由代理實現。?在List中保存注冊順序,創建具有指定順序接口的JDK代理。*/private?List<Class>?interfaces?=?new?ArrayList<Class>();/**Advisor名單?如果添加了一個Advise,它將被包裝在一個Advisor中,然后被添加到此列表中。*/private?List<Advisor>?advisors?=?new?LinkedList<Advisor>();/***?Array?updated?on?changes?to?the?advisors?list,?which?is?easier*?to?manipulate?internally.*/private?Advisor[]?advisorArray?=?new?Advisor[0];}}1.2.4?ProxyCreatorSupport
proxy factory的基類
public?class?ProxyCreatorSupport?extends?AdvisedSupport?{//允許在不改變核心框架的情況下選擇不同的策略。private?AopProxyFactory?aopProxyFactory;private?List<AdvisedSupportListener>?listeners?=?new?LinkedList<AdvisedSupportListener>();/**?Set?to?true?when?the?first?AOP?proxy?has?been?created?*/private?boolean?active?=?false;}1.2.5 生成序列圖
需要關注:
1.生成代理時機:在afterPropertiesSet中,(對應10. InitializingBean's afterPropertiesSet)
2.委派給AopProxy具體實現類生成代理對象。
1.3 AOP 攔截器實現(具體發生在每次函數調用過程中)
Advisor規則應用過程,發生在具體方法調用過程中,此時代理對象已經生成了。
主要工作:
維護Advisor鏈
匹配過程,主要通過Pointcut中的ClassFiter,和MethodMatcher完成。
2.TransactionProxyFactoryBean 對象剖析
2.1 類圖
2.1.1?ProxyConfig
方便的用于創建代理的超類配置,以確保所有代理創建者具有一致的屬性。
public?class?ProxyConfig?implements?Serializable?{/***???設置是否直接代理目標類,而不是僅代理特定的接口。?默認值為“false”。* 將其設置為“true”以強制對TargetSource的暴露目標類進行代理。?* 如果該目標類是接口,將為給定的接口創建一個JDK代理。?*???如果該目標類是任何其他類,將為給定的類創建一個CGLIB代理。*/private?boolean?proxyTargetClass?=?false;/***設置代理是否應該執行積極的優化。?“aggressive?optimizations”的確切含義在代理之間有所不同,但通常有一些權衡。?默認值為“false”。*例如,優化通常意味著建議更改在代理創建后不會生效。?*因此,默認情況下禁用優化。?如果其他設置排除優化,則可以忽略“true”的優化值:例如,如果“publicProxy”設置為“true”,并且與優化不兼容。*/private?boolean?optimize?=?false;/***設置是否應該阻止通過此配置創建的代理被轉換為Advised,以查詢代理狀態。*默認為“false”,這意味著任何AOP代理可以轉換為Advised。*/boolean?opaque?=?false;/**是否可以被AOP框架作為ThreadLocal暴露,通過AopContext。默認false,以避免不必要的額外攔截*/boolean?exposeProxy?=?false;/***?設置此配置是否應該被凍結。當配置被凍結時,不會改變任何advice。?這對于優化是有用的,*/private?boolean?frozen?=?false; }2.1.2?AbstractSingletonProxyFactoryBean
方便的FactoryBean類型的超類,產生單例范圍的代理對象。
public?abstract?class?AbstractSingletonProxyFactoryBean?extends?ProxyConfigimplements?FactoryBean<Object>,?BeanClassLoaderAware,?InitializingBean?{//目標對象private?Object?target;//被代理的一組接口private?Class<?>[]?proxyInterfaces;//在隱式”事務“攔截器之前設置要應用的interceptors?(or?advisors)?private?Object[]?preInterceptors;//在隱式”事務“攔截器后設置要應用的interceptors?(or?advisors)?private?Object[]?postInterceptors;//Specify?the?AdvisorAdapterRegistry?to?use.?Default?is?the?global?AdvisorAdapterRegistry.private?AdvisorAdapterRegistry?advisorAdapterRegistry?=?GlobalAdvisorAdapterRegistry.getInstance();//生成代理的ClassLoaderprivate?transient?ClassLoader?proxyClassLoader;private?Object?proxy;????? }2.1.3?TransactionProxyFactoryBean
代理工廠bean,用于簡化的聲明性事務處理。
public?class?TransactionProxyFactoryBean?extends?AbstractSingletonProxyFactoryBeanimplements?BeanFactoryAware?{//設置事務管理器。?這將執行實際的事務管理:這個類只是一種調用它的方式。private?final?TransactionInterceptor?transactionInterceptor?=?new?TransactionInterceptor();設置一個pointcut,即根據傳遞的方法和屬性可以導致TransactionInterceptor的條件調用的bean。?注意:總是調用其他攔截器。private?Pointcut?pointcut;//將方法名稱的屬性設置為鍵和事務屬性描述符(通過TransactionAttributeEditor解析)public?void?setTransactionAttributes(Properties?transactionAttributes)?{this.transactionInterceptor.setTransactionAttributes(transactionAttributes);} //設置用于查找事務屬性的事務屬性源。?如果指定一個String屬性值,PropertyEditor將從該值創建一個MethodMapTransactionAttributeSource。public?void?setTransactionAttributeSource(TransactionAttributeSource?transactionAttributeSource)?{this.transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);}?????? }2.1.4 使用配置
???<bean?id="baseTransactionProxy"?class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"abstract="true"><property?name="transactionManager"?ref="transactionManager"/><property?name="transactionAttributes"><props><prop?key="insert*">PROPAGATION_REQUIRED</prop><prop?key="update*">PROPAGATION_REQUIRED</prop><prop?key="*">PROPAGATION_REQUIRED,readOnly</prop></props></property></bean><bean?id="myProxy"?parent="baseTransactionProxy"><property?name="target"?ref="myTarget"/></bean><bean?id="yourProxy"?parent="baseTransactionProxy"><property?name="target"?ref="yourTarget"/></bean>2.2?TransactionProxyFactoryBean分析
2.2.1類圖
2.2.2 序列圖
事務模板入口
org.springframework.transaction.interceptor.TransactionInterceptor
public Object invoke(@NotNull MethodInvocation invocation)
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()?{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);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?exceptioncompleteTransactionAfterThrowing(txInfo,?ex);throw?ex;}finally?{cleanupTransactionInfo(txInfo);}commitTransactionAfterReturning(txInfo);return?retVal;}else?{//?It's?a?CallbackPreferringPlatformTransactionManager:?pass?a?TransactionCallback?in.try?{Object?result?=?((CallbackPreferringPlatformTransactionManager)?tm).execute(txAttr,new?TransactionCallback<Object>()?{public?Object?doInTransaction(TransactionStatus?status)?{TransactionInfo?txInfo?=?prepareTransactionInfo(tm,?txAttr,?joinpointIdentification,?status);try?{return?invocation.proceedWithInvocation();}catch?(Throwable?ex)?{if?(txAttr.rollbackOn(ex))?{//?A?RuntimeException:?will?lead?to?a?rollback.if?(ex?instanceof?RuntimeException)?{throw?(RuntimeException)?ex;}else?{throw?new?ThrowableHolderException(ex);}}else?{//?A?normal?return?value:?will?lead?to?a?commit.return?new?ThrowableHolder(ex);}}finally?{cleanupTransactionInfo(txInfo);}}});//?Check?result:?It?might?indicate?a?Throwable?to?rethrow.if?(result?instanceof?ThrowableHolder)?{throw?((ThrowableHolder)?result).getThrowable();}else?{return?result;}}catch?(ThrowableHolderException?ex)?{throw?ex.getCause();}} }轉載于:https://blog.51cto.com/dba10g/1927762
總結
以上是生活随笔為你收集整理的spring事务管理 TransactionProxyFactoryBean源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Redis官方文档》事件库
- 下一篇: 重构机房收费系统你要用的——异常处理和抛