新聞中心
使用AopContxt.currentProxy()方法可獲取當(dāng)前類的代理對象(是通過StaticUnadvisedExposedInterceptor或DynamicUnadvisedExposedInterceptor或JdkDynamicAopProxy#invoke中設(shè)置的,@EnableAspectJAutoProxy#exposeProxy可設(shè)置為true,將當(dāng)前的aop對象暴露到AopContext的ThreadLocal變量currentProxy中)
在使用@Transactional注解聲明事務(wù)時,會有以下四種情況:
在不同類中,事務(wù)方法A調(diào)用非事務(wù)方法B,事務(wù)具有傳播性,事務(wù)生效;
在不同類中,非事務(wù)方法A調(diào)用事務(wù)方法B,事務(wù)生效;
在同一個類中,事務(wù)方法A調(diào)用非事務(wù)方法B,事務(wù)生效;
在同一個類中,非事務(wù)方法A調(diào)用事務(wù)方法B,事務(wù)失效,這是由于使用Spring AOP代理造成的,只有當(dāng)事務(wù)方法被當(dāng)前類以外的代碼調(diào)用時,才會由Spring生成的代理對象來管理。
解決辦法:
- 采用AopContext.currentProxy().方法B名()來進行調(diào)用
- ApplicationContext.getBean()
- 在當(dāng)前類中注入自己
- 使用手動事務(wù)
如果該類存在@Async異步任務(wù)方法,那么@Async方法應(yīng)該使用第3種方式并且在引入的自身代理對象上加上@Lazy注解,讓其再進行代理封裝(看這里: Spring AOP入門以及基于XML的Spring AOP配置的深入學(xué)習(xí)與使用【兩萬字】_劉Java的博客-博客)
思考:為什么在被代理類的方法中調(diào)用被代理的其它方法時,不經(jīng)過增強方法呢?
這是由aop的實現(xiàn)機制決定的,spring aop抽象出了TargetSource接口(從中可以獲取target目標(biāo)對象),當(dāng)外部通過調(diào)用代理對象的方法時,就會經(jīng)過MethodInterceptor方法攔截器(增強方法),當(dāng)所有的方法攔截器都調(diào)用完了(責(zé)任鏈模式),就會從代理配置(ProxyFactory->ProxyCreatorSupport->AdvisedSupport中維護targetSource)的TargetSource中獲取到目標(biāo)對象,然后使用反射調(diào)用該目標(biāo)對象的目標(biāo)方法,也就是最終目標(biāo)對象執(zhí)行時,其實這個時候已經(jīng)不是代理對象了,此時是目標(biāo)對象!那么反射方法執(zhí)行時,方法中的this,就是目標(biāo)對象,那在一個成員方法中調(diào)用類中的另外一個成員方法(此時省略了this),省略的這個this是目標(biāo)對象,而不是代理對象,因此被調(diào)用的另外一個成員方法時,是不會經(jīng)過增強方法的(方法攔截器)。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
本文題目:AopContxt.currentProxy()-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://ef60e0e.cn/article/dhddcs.html