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