當前位置:編程學習大全網 - 編程語言 - 面試官:Spring 註解 @After,@Around,@Before 的執行順序是?

面試官:Spring 註解 @After,@Around,@Before 的執行順序是?

AOP中有 @Before , @After , @Around , @AfterRunning 註解等等。

首先上下自己的代碼,定義了切點的定義

@Before , @After , @Around 註解的區別大家可以自行百度下。

總之就是 @Around 可以實現 @Before 和 @After 的功能,並且只需要在壹個方法中就可以實現。

首先我們來測試壹個方法用於獲取數據庫壹條記錄的

以下是控制臺打印的日誌

可以看到,因為沒有匹配 @Around 的規則,所以沒有進行環繞通知。(PS:我定義的環繞通知意思是要符合是 controller 包下的方法並且方法必須帶有參數,而上述方法沒有參數,所以只走了 @before 和 @after 方法,不符合 @Around 的匹配邏輯)

我們再試壹下另壹個帶有參數的方法

以下是該部分代碼的console打印

顯而易見,該方法符合 @Around 環繞通知的匹配規則,所以進入了 @Around 的邏輯,但是發現了問題,所有的方法都被執行了2次,不管是切面層還是方法層。(有人估計要問我不是用的自定義註解 @RedisCache(type = Response.class) 麽。為什麽會符合 @Around 的匹配規則呢,這個等會在下面說)

我們分析日誌的打印順序可以得出,在執行環繞方法時候,會優先進入 @Around 下的方法。 @Around 的方法再貼壹下代碼。

打印了前兩行代碼以後,轉而去執行了 @Before 方法,是因為中途觸發了 ProceedingJoinPoint.proceed() 方法。

這個方法的作用是執行被代理的方法,也就是說執行了這個方法之後會執行我們controller的方法,而後執行 @before , @after ,然後回到@Around執行未執行的方法,最後執行 @afterRunning ,如果有異常拋出能執行 @AfterThrowing

也就是說環繞的執行順序是 @Around @Before @After @Around 執行 ProceedingJoinPoint.proceed() 之後的操作 @AfterRunning (如果有異常 @AfterThrowing )

而我們上述的日誌相當於把上述結果執行了2遍,根本原因在於 ProceedingJoinPoint.proceed() 這個方法,可以發現在@Around 方法中我們使用了2次這個方法,然而每次調用這個方法時都會走壹次 @Before @After @Around 執行 ProceedingJoinPoint.proceed() 之後的操作 @AfterRunning (如果有異常 @AfterThrowing )。

因此問題是出現在這裏。所以更改 @Around 部分的代碼即可解決該問題。更改之後的代碼如下:

更改代碼之後的運行結果

回到上述未解決的問題,為什麽我定義了切面的另壹個註解還可以進入@Around方法呢?

因為我們的方法仍然在controller下,因此滿足該需求,如果我們定義了controller包下的某個controller才有用。

例如:

而如果我們剛才定義的方法是寫在 TestController 之下的,那麽就不符合 @Around 方法的匹配規則了,也不符合 @before 和 @after 的註解規則,因此不會匹配任何壹個規則,如果需要匹配特定的方法,可以用自定義的註解形式或者特性controller下的方法

①:特性的註解形式

然後在所需要的方法上加入 @RedisCache 註解,在 @Before , @After , @Around 等方法上添加該切點的方法名(“ annoationPoint() ”),如果有多個註解需要匹配則用 || 隔開

②:指定controller或者指定controller下的方法

該部分代碼是指定了 com.lmx.blog.controller 包下的UserController下的所有方法。

第壹個 * 代表的是返回類型不限

第二個 * 代表的是該controller下的所有方法, (..) 代表的是參數不限

當方法符合切點規則不符合環繞通知的規則時候,執行的順序如下

@Before @After @AfterRunning(如果有異常 @AfterThrowing)

當方法符合切點規則並且符合環繞通知的規則時候,執行的順序如下

@Around @Before @Around @After執行 ProceedingJoinPoint.proceed() 之後的操作 @AfterRunning(如果有異常 @AfterThrowing)

  • 上一篇:生化機器人的分類
  • 下一篇:江蘇交行面試通知已出,歷年面試真題告訴妳怎樣備考通過率高!
  • copyright 2024編程學習大全網