1. 程式人生 > >面向切面的 Spring —— 如何通過切點來選擇連線點?

面向切面的 Spring —— 如何通過切點來選擇連線點?

Q:切點的作用是什麼?
A:切點用於準確定位應該在什麼地方應用切面的通知。

在 Spring AOP 中,要使用 AspectJ 的切點表示式語言定義切點

下表為 Spring AOP 所支援的 AspectJ 切點指示器:
這裡寫圖片描述

在 Spring 中嘗試使用 AspectJ 其他指示器時,將會丟擲 IllegalArgument-Exception 異常。

注意:只有 execution 指示器實際執行匹配的,而其他的指示器都是用來限制匹配的

Q:如何編寫切點?

A: 如下所示:

package concert;

/**
 * Performance 可以代表任何型別的現場表演,如舞臺劇、電影或音樂會。
 * 假設我們想要編寫 Performance 的 perform() 方法觸發的通知。
 */
public interface Performance { public void perform(); }

下圖展示一個切點表示式,這個表示式能夠設定當 perform() 方法執行時觸發通知的呼叫。
這裡寫圖片描述
方法表示式以 “*” 號開始,表明了我們不關心方法返回值的型別。然後,我們指定了全限定類名和方法名。對於方法引數列表,我們使用兩個點號 (..) 表明切點要選擇任意的 perform() 方法,無論方法的入參是什麼。

假設我們需要配置的切點僅匹配 concert 包。在此場景下,可以使用 within() 指示器來限制匹配。
這裡寫圖片描述
使用 “&&” 操作符把 execution()

within() 指示器連線在一起形成與(and)關係(切點必須匹配所有的指示器)。類似的,我們可以使用 “||” 操作符來標識或(or)關係,而使用 “!” 操作符來標識非(not)操作。

注意:因為 “&” 在 XML 中有特殊含義,所以在 Spring 的 XML 配置裡面描述切點時,使用 and 來代替 “&&”。同樣,or 和 not 可以分別來代替 “||” 和 “!”

Q:如何在切點中選擇 bean?

A: Spring 還引入了一個新的 bean() 指示器,它允許我們在切點表示式中使用 bean 的 ID 來標識 bean。bean() 使用 bean ID 或 bean 名稱作為引數來限制切點只匹配特定的 bean。

// 希望在執行 Performance 的 perform() 方法時應用通知,但限定 bean 的 ID 為 woodstock
execution(* concert.Performance.perform()) and bean('woodstock')

//或者使用非操作符作為除了特定 ID 以外的其他 bean 應用通知。
execution(* concert.Performance.perform()) and !bean('woodstock')