解決AOP切面在巢狀方法呼叫時不生效問題

2021-10-05 00:23:20 字數 2908 閱讀 9792

在使用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...