在之前工作中遇到過(guò)同個(gè)類中事務(wù)調(diào)用失效的情況铐刘,原因是SpingAop不支持同個(gè)類中事務(wù)調(diào)用【@Transactional也一樣朋蔫,因?yàn)镾pring中Transactional 也是基于AOP的 】欣硼,如下:
定義一個(gè)切面骑冗,檢查DemoCheck注解.png
定義DemoCheck注解.png
Demo中有兩個(gè)方法:sayHello方法被@DemoCheck標(biāo)注秉宿,因此這是一個(gè)切點(diǎn)疙剑。
test方法調(diào)用sayHello方法氯迂。
Demo.png
執(zhí)行sayHello方法測(cè)試:這里預(yù)期結(jié)果是執(zhí)行切面,實(shí)際也執(zhí)行了言缤,沒(méi)什么問(wèn)題
執(zhí)行方法.png
結(jié)果.png
執(zhí)行test方法測(cè)試:這里預(yù)期結(jié)果首先執(zhí)行test方法嚼蚀,調(diào)用sayhello方法時(shí)執(zhí)行切面。結(jié)果并沒(méi)有執(zhí)行切面管挟,可見(jiàn)aop失效
結(jié)果.png
原因分析
springAop是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)的(不論是jdk還是cglib)轿曙,它將代理對(duì)象注入到spring容器中。當(dāng)調(diào)用demo【代理對(duì)象】的test方法時(shí)僻孝,先執(zhí)行切面(此處無(wú)切面)导帝,在執(zhí)行被代理對(duì)象【實(shí)際對(duì)象】的test的方法,在實(shí)際對(duì)象的test中調(diào)用sayhello【其實(shí)this.hello更好理解】自然沒(méi)有aop效果穿铆。
我們可以通過(guò)輸入幾個(gè)對(duì)象hashCode來(lái)驗(yàn)證一下:可見(jiàn)執(zhí)行test和sayHello都是被代理對(duì)象【實(shí)際對(duì)象】
HashCode.png
解決方法
解決辦法只需調(diào)用Spring容器中的test方法就好了您单,因此我們可以在原對(duì)象中定義一個(gè)代理對(duì)象的引用
改造后.png
結(jié)果.png