1.前置通知
在目標方法執行之前執行執行的通知。
前置通知方法,可以沒有參數,也可以額外接收一個JoinPoint,Spring會自動將該對象傳入,代表當前的連接點,通過該對象可以獲取目標對象 和 目標方法相關的信息。
注意,如果接收JoinPoint,必須保證其爲方法的第一個參數,否則報錯
配置方法:
2.環繞通知
在目標方法執行之前和之後都可以執行額外代碼的通知。
在環繞通知中必須顯式的調用目標方法,否則目標方法不會執行。
這個顯式調用是通過ProceedingJoinPoint來實現的,可以在環繞通知中接收一個此類型的形參,spring容器會自動將該對象傳入,這個參數必須處在環繞通知的第一個形參位置。
**ProceedingJoinPoint時JoinPoint的子類,要注意,只有環繞通知可以接收ProceedingJoinPoint,而其他通知只能接收JoinPoint。
配置方式:
環繞通知需要返回返回值,否則真正調用者將拿不到返回值,只能得到一個null。
環繞通知有以下能力
- 控制目標方法是否執行
- 目標方法執行之前或之後執行額外代碼
- 控制是否返回返回值
- 改變返回值
環繞通知雖然有這樣的能力,但一定要慎用(因爲在裏面可以修改方法的返回值等信息),要小心不要破壞了軟件分層的“高內聚 低耦合”的目標。
3.後置通知
在目標方法執行之後成功執行的通知。
在後置通知中也可以選擇性的接收一個JoinPoint來獲取連接點的額外信息,但是這個參數必須處在參數列表的第一個。
在後置通知中,還可以通過配置獲取目標方法的返回值
一定要保證JoinPoint處在參數列表的第一位,否則拋異常
4.異常通知
在目標方法拋出異常時執行的通知
配置方法
可以配置傳入JoinPoint獲取目標對象和目標方法相關信息,但必須處在參數列表第一位
另外,還可以配置參數,讓異常通知接收到目標方法拋出的異常對象
5.最終通知
是在目標方法執行之後執行的通知。和後置通知不同之處在於,後置通知是在方法正常返回後執行的通知,如果方法沒有正常返-例如拋出異常,則後置通知不會執行。而最終通知無論如何都會在目標方法調用過後執行,即使目標方法沒有正常的執行完成。另外,後置通知可以通過配置得到返回值,而最終通知無法得到。
配置方式:
最終通知也可以額外接收一個JoinPoint參數,來獲取目標對象和目標方法相關信息,但一定要保證必須是第一個參數。
6.五種通知執行位置
7.五種通知執行的順序
7.1在目標方法沒有拋出異常的情況下
*前置通知* *環繞通知的調用目標方法之前的代碼*//取決於配置順序 目標方法 *環繞通知的調用目標方法之後的代碼* *後置通知 *最終通知//取決於配置順序 |
7.2在目標方法拋出異常的情況下
*前置通知* *環繞通知的調用目標方法之前的代碼*//取決於配置順序 目標方法 拋出異常 *異常通知* *最終通知*//取決於配置順序 |
7.3如果存在多個切面
多切面執行時,採用了責任鏈設計模式。
切面的配置順序決定了切面的執行順序,多個切面執行的過程,類似於方法調用的過程,在環繞通知的proceed()執行時,去執行下一個切面或如果沒有下一個切面執行目標方法,從而達成了如下的執行過程:
如果目標方法拋出異常
8.五種通知的常見使用場景
前置通知 |
記錄日誌(方法將被調用) |
環繞通知 |
控制事務 權限控制 |
後置通知 |
記錄日誌(方法已經成功調用) |
異常通知 |
異常處理 控制事務 |
最終通知 |
記錄日誌(方法已經調用,但不一定成功) |