Spring事務切面原理
一、前言
本節我們來談談 <tx:advice/>、<aop:config>
標籤如何建立事務切面的。
二、<tx:advice/>、<aop:config> 標籤如何建立事務切面的
<tx:advice/>
標籤作用是建立一個TransactionInterceptor,作為事務切面的通知方法。在Spring中(可以參考:https://gitbook.cn/gitchat/activity/5a8fdf6bf2e5dc2ca621a937) Advisor這個概念是從 Spring 1.2的 AOP 支援中提出的,一個 Advisor 相當於一個小型的切面,不同的是它只有一個通知(Advice),Advisor中還包含一個pointcut(切點),切點定義了對那些方法進行攔截,而通知是具體對攔截到的方法進行增強的邏輯。
具體對<tx:advice/>
標籤進行解析的是TxAdviceBeanDefinitionParser,其時序圖如下:
首先TxAdviceBeanDefinitionParser有getBeanClass方法程式碼程式碼:
protected Class<?> getBeanClass(Element element) {
return TransactionInterceptor.class;
}
這說明該標籤解析後生成的是TransactionInterceptor物件的bean定義。
其中時序圖中步驟(2)是設定配置demo的XML配置檔案裡面建立的事務管理器到TransactionInterceptor物件,
時序圖(4)~(10)則解析
<tx:advice/>
標籤中事務屬性值設定到TransactionInterceptor物件裡面屬性裡面。
注:也就是<tx:advice/>
標籤的作用是生成一個TransactionInterceptor攔擊器物件,並設定該物件的一些事務屬性,然後該物件將作為事務切面的通知方法。
<aop:config>
標籤作用是建立一個DefaultBeanFactoryPointcutAdvisor(其實現了Advisor介面)物件作為作一個Advisor,前面說了一個Advisor就是一個小型的切面,所以其中定義了切點和通知。該標籤是ConfigBeanDefinitionParser類進行解析的,其時序圖如下:
時序圖中步驟(2)建立了一個DefaultBeanFactoryPointcutAdvisor物件的bean定義,步驟(3)(4)則是設定上面建立的通知物件(TransactionInterceptor)到該Advisor
時序圖中步驟(8)則是解析標籤中的切點表示式,然後設定到DefaultBeanFactoryPointcutAdvisor物件的bean定義。
時序圖步驟(4)註冊了一個AspectJAwareAdvisorAutoProxyCreator到Spring容器,作用就是對滿足pointcut表示式的類的方法進行代理,並且使用advice進行攔截處理,而advice就是事務攔截器。
由於AspectJAwareAdvisorAutoProxyCreator類實現了BeanPostProcessor介面,所以具有postProcessAfterInitialization方法,而對符合切點的方法進行代理就是在該方法內的wrapIfNecessary方法:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
// 8.1
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//8.2
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;
}
其中8.1查詢所有可以對當前bean進行增強的切面,其中有一個條件就是看那些bean實現了Advisor介面,而<aop:config>
標籤作用是建立一個DefaultBeanFactoryPointcutAdvisor,並且其實現了Advisor介面,所以這裡會使用DefaultBeanFactoryPointcutAdvisor切面,然後會看當前bean的方法是否滿足切面的切點表示式,具體是AopUtils的canApply方法進行判斷:
如果滿足則執行8.2對方法進行代理,這裡會對TestTransactionProgagationUserImpl、TestTransactionProgagationCourseImpl、UserManagerBoImpl類的所有方法進行事務代理。
注:Spring框架中一個 Advisor 相當於一個小型的切面,<tx:advice/>
定義了這個切面的通知方法,而<aop:config>
具體定義了一個Advisor切面,並且內部定義了一個切點,並且引入了<tx:advice/>
定義的通知方法
最後
想了解更多關於粘包半包問題單擊我
更多關於分散式系統中服務降級策略的知識可以單擊 單擊我
想系統學dubbo的單擊我
想學併發的童鞋可以 單擊我