在使用aop切面程式設計中,通常會遇到乙個方法巢狀呼叫,導致aop不生效的問題。
如下面所說明的:
在乙個實現類中,有2個方法,方法a,方法b,其中方法b上面有個註解切面,當方法b被外部呼叫的時候,會進入切面方法。
但當方法b是被方法a呼叫時,並不能從方法b的註解上,進入到切面方法,即我們經常碰到的方法巢狀時,aop註解不生效的問題。
通過外部,呼叫方法b,可以正常進入切面方法,這個場景的**如下:
註解類:
@target()
@retention
(retentionpolicy.runtime)
public @inte***ce
demoanno
切面類:
@aspect
@order(-
1)@component
public
class
demoaspect
}
介面類:
public
inte***ce
demoservice
服務實現類:
@service
public
class
demoserviceimpl
implements
demoservice
@override
@demoanno
public
void
methoddemob()
}
測試方法:
@autowired
demoservice demoservice;
@test
public
void
testmethod()
輸出結果:
this is method a
before method b, print 'hello,world'
this is method b
在這個場景測試過程中,我們通過在單元測試類中,直接呼叫方法b,可以正常進入切面中;
上面的**,做下修改。在demoserviceimpl實現類中,通過方法a去呼叫方法b,然後再單元測試類中,呼叫方法a。**修改後如下:
服務實現類:
@service
public
class
demoserviceimpl
implements
demoservice
@override
@demoanno
public
void
methoddemob()
}
單元測試類:
@autowired
demoservice demoservice;
@test
public
void
testmethod()
通過修改呼叫方式後,列印的結果如下:
this is method a
this is method b
結果顯示,方法b上面的切面,並未生效,沒有進入到切面方法中。
場景1中,通過外部呼叫方法b,是由於spring在啟動時,根據切面類及註解,生成了demoservice的**類,在呼叫方法b時,實際上是**類先對目標方法進行了業務增強處理(執行切面類中的業務邏輯),然後再呼叫方法b本身。所以場景1可以正常進入切面方法;
下圖斷點時可以看到demoservice物件,是乙個cglib的**物件。
場景2中,通過外部呼叫的是方法a,雖然spring也會建立乙個cglib的**類去呼叫方法a,但當方法a呼叫方法b的時候,屬於類裡面的內部呼叫,使用的是例項物件本身去去呼叫方法b,非aop的cglib**物件呼叫,方法b自然就不會進入到切面方法了。
對於場景2,我們在業務開發過程中經常會碰到,但我們期望的是,方法a在呼叫方法b的時候,仍然能夠進入切面方法,即需要aop切面生效。
這種情況下,我們在呼叫方法b的時候,需要使用aopcontext.currentproxy()獲取當前的**物件,然後使用**物件呼叫方法b。
注:需要開啟exposeproxy=true的配置,springboot專案中,可以在啟動類上面,新增 @enableaspectjautoproxy(exposeproxy = true)註解。
@service
public
class
demoserviceimpl
implements
demoservice
@override
@demoanno
public
void
methoddemob()
}
改造後,再執行單元測試類:
@autowired
demoservice demoservice;
@test
public
void
testmethod()
列印結果如下:
this is method a
before method b, print 'hello,world'
this is method b
問題完美解決!!! aop切面 註解 引數獲取方法
在工作中會經常使用aop,這裡將aop使用基本方法,獲取在切點中使用的獲取引數 註解做乙個樣例。1 定義需要切面的註解 target elementtype.method retention retentionpolicy.runtime documented public inte ce annd...
面向切面程式設計AOP 在iOS中的實現
aop為aspect oriented programming的縮寫,意為 面向切面程式設計 通過預編譯 方式和執行期動態 實現程式功能的統一維護的一種技術。我的理解就是將每個特定的物件需要執行的同樣的 提煉出來,然後動態的載入到每個物件中。實現主要用到了兩個知識點,乙個是runtime程式設計,乙...
AOP切面實現方法日誌列印耗時計算
很簡單,通過aop實現每個方法訪問時候統一進行日誌列印和耗時計算,在spring配置xml檔案中設定啟用aop aspect component public class loggingaspect args resultdata joinpoint.proceed args long endtim...