Spring事務內方法呼叫自身事務 增強的三種方式
ServiceA.java檔案:
檢視Spring Tx的相關日誌: 可以看到只建立了一個事物ServiceA.service方法的事務,但是callSelf方法卻沒有被事務增強;
分析原因:Spring事務生成的物件也是被Cglib或JDK代理的物件,就區別於該物件本身了,
代理的物件執行方法之前會走攔截器鏈,就不能同this方法.
解決方案:
- 使用Autowired註解將自身注入,然後呼叫注入屬性的方法;
驗證輸出結果: 確實初始化了callSelf的事務;
2.之前Aop可以將代理物件暴露到當前執行緒區域性變數中;
<aop:aspectj-autoproxy expose-proxy="true"/>
通過嘗試發現,SpringTx也可以使用該配置,將建立的物件加入到當前執行緒區域性變數;
也許覺得SpringAop和SpringTx不一樣啊,但其實兩者都實現了AbstractAutoProxyCreator類,同樣設定expose-proxy也能生效,繫結到執行緒區域性變數上;
呼叫方式如下:
驗證輸出結果:可以看到確實 callSelf方法也被Spring事務增強到了.
3.按照道理來說tx:annotation-driven標籤應該也有expose-proxy屬性,但是很不幸:
<tx:annotation-driven>標籤確實不允許expose-proxy屬性設定,有proxy-target-class屬性;
檢視AopNamespaceUtils的useClassProxyingIfNecessary方法:
Line 91-94行是用來解析標籤時候定義expose-proxy、proxy-target-class兩個屬性,Aop以及Tx都會呼叫這個方法, 問題就是這裡了, <aop:aspectj-autoproxy>標籤約束裡有expose-proxy,
那可以解析,但是<tx:annotation-driven>標籤沒有expose-proxy我解析啥子呢,
改動下解析Tx標籤時,將expose-proxy設定為true; (此處涉及到改動原始碼,jar包是無法直接修改的,我修改的Spring的原始碼,如果需要匯入Spring的jar包 然後在修改之後匯出成jar包)
驗證下輸出結果: 可以看到也實現了呼叫自身方法, 其實和方法二應該是一個意思;
附上筆記地址: