在實(shí)際編寫切面方法和應(yīng)用切面的時(shí)候,發(fā)現(xiàn)在對象內(nèi)的方法之間調(diào)用蜓洪,是不會進(jìn)入定義在方法上的切面的整吆。
場景
存在一個(gè)bean對象,對bean對象的兩個(gè)方法methodA和methodB都應(yīng)用了切面拧略。在methodA方法里會調(diào)用methodB方法。
現(xiàn)在從外部調(diào)用bean.methodA()瘪弓,其實(shí)你希望得到的效果是:
proxy bean
methodAP() ---> methodA
|
/---------------/
|
V
methodBP() ---> methodB
而實(shí)際得到的效果是
proxy bean
methodAP() ---> methodA
|
V
methodBP() ---> methodB
原因分析
在methodA內(nèi)部調(diào)用methodB時(shí)垫蛆,方法是直接進(jìn)行調(diào)用,并不會調(diào)用到代理對象的代理方法上腺怯。
解決方案
重構(gòu)代碼
methodA不調(diào)用methodB
methodA和methodB放置在兩個(gè)不同的類中
將methodB的切面方法代理邏輯合并到methodB的代理邏輯中
使用AspectJ進(jìn)行編譯織入
-
顯式調(diào)用代理對象的方法
public void methodA(){ ((BeanClassName)AopContext.currentProxy()).methodB(); }
目前袱饭,推薦的也只有第一種方法。對代碼進(jìn)行重構(gòu)呛占,methodB可能就不應(yīng)該允許從外面進(jìn)行調(diào)用虑乖。而第二種會影響所有的切面,而且需要借助aspectJ來進(jìn)行編譯晾虑。第三種對代碼有侵入性疹味。