Spring學習之旅(六)Spring AOP工作原理初探,springaop
AOP(Aspect-Oriented Programming,面向切面編程)是Spring提供的關鍵技術之一。
AOP基於IoC,是對OOP(Object-Oriented Programming,物件導向編程)的有效補充。
利用一種“橫切”的技術,剖解鎖裝的對象內部,並將那些影響了多個類的公用行為封裝到一個可重用模組,並將其命名為Aspect(切面,也稱方面)。
AOP的核心思想就是“將應用程式中的商務邏輯與對其提供支援的泛型服務功能進行分離,而商務邏輯與泛型服務功能之間通過配置資訊,實現整合”。
實現AOP的技術主要分為兩大類:
一是採用動態代理技術,採用攔截器截取訊息的方法,對該訊息進行“插裝”,以取代原有對象行為的執行;
二是採用靜態織入的方式,引入特定的文法建立“切面”,從而使得編譯器可以在編譯期間織入有關“切面”代碼。
Spring AOP是實現AOP的一種技術,是採用“動態代理技術”實現的。
(一)AOP技術相關的概念和術語
1)幾個相關概念:
在小編的上篇博文中,在對原來的商務邏輯進行處理加入AOP部分時,類A中所有方法的執行前後,都成為了“所關注的地方”,這個地方稱為“橫切關注點”。這樣原來的商務邏輯被分割開來,所以這個點也就成了聯絡前後邏輯的連接點,稱為“連接點”。然後,對於整個原來的商務邏輯,我們需要告訴程式“在什麼時候添加新的附加功能”,這裡的“什麼時候”的時機稱為“通知”。在本例中“通知”有兩個:“在類A中所有方法的執行前添加”稱為“前置通知”;“類A中所有方法的執行後添加”稱為“後置通知”。
例子中前置通知:
<!-- 配置前置通知及前置通知的切入點 --><aop:before method="methodX1" pointcut="execution(* com.edu.aop.hello.A.*())"></aop:before>
後置通知:
<!-- 配置後置通知及後置通知的切入點 --><aop:after method="methodX2" pointcut="execution(* com.edu.aop.hello.A.*())"></aop:after>
當原來的商務邏輯被“橫向關注點”分割後,就可以在“該點”處插入(切入)新需求功能模組,這裡將指明插入(切入)新需求功能模組的“地方”(設定檔代碼部分)稱為“切入點(Pointcut)”,而要插入的功能模組,稱為“切面(Aspect)”。可見,配置“切面”就是指出:在什麼地方(連接點)切入什麼模組(切面)的哪個方法
2)Aspect(切面,也稱方面)
是對系統中橫切關注點邏輯進行模組化封裝的AOP概念實體(就是定義一個類),它可以包含多個Pointcut(切入點)及相關的Advice(通知)定義。例如本例中的類X。
3)JoinPoint(連接點)
系統在運行之前,AOP的功能模組需要織入到OOP的功能模組中。要進行這種織入過程,需要知道在系統的哪些功能點上進行織入操作,這些將要在其上進行織入操作的系統功能點稱為JoinPoint。
在Spring AOP中,一個連接點總是表示一個方法的執行。
常見的幾種JoinPoint類型:方法調用、方法執行、構造方法調用、構造方法執行、欄位設定、欄位擷取、異常處理執行、類初始化。
4)Pointcut(切入點)
Pointcut是對JointPoint的形式描述,用於指出要對哪些Joinpoint進行攔截的定義。
(初學可理解為二者相同,只不過Pointcut用在設定檔的通知中;JoinPoint用在切面類中)
Pointcut通常和“一個切入點運算式”相關聯,來表示在需要在哪些功能點上織入AOP的功能。
常見的Pointcut方式:
(1)直接指定JoinPoint所在的方法名稱;
(2)Regex,Spring的AOP支援該種方式;
(3)使用特定的Pointcut表述語言。
5)Advice(通知)
一個Advice對應一個橫切關注點邏輯的載體,它代表將會織入到JointPoint的橫切邏輯:在切面的某個特定的連接點上執行的邏輯。
一個切麵包括一個或者多個通知,每個通知就是告訴“在什麼時機”調用執行什麼方法。
Spring AOP提供了5種通知:
Before Advice(前置通知)、After Returning Advice(返回通知)、After throwing Advice(異常通知)、After Advice(後置通知)、Around Advice(環繞通知)
6)Target(目標對象)
通知被應用的對象(包含連接點的對象,或者說被通知或被代理的對象),即符合Pointcut所指定的條件,將在織入過程中被織入橫切邏輯的對象。
本例中,即是A類的所有方法。
7)AOP Proxy(AOP 代理)
AOP架構建立的對象,用來執行切面(Aspect)的內容。
8)Weave(織入)
將Aspect應用到Target對象並導致Proxy對象建立的過程稱為織入。
9)攔截機(Interceptor)
攔截器(也稱攔截機)是AOP的另一種叫法。
(二)切入點運算式
通常,切入點運算式用於給出Pointcut對JointPoint的形式描述,指出要對哪些JoinPoint進行攔截。
切入點運算式的格式如下:
execution(方法存取權限 傳回型別 方法的包路徑.方法名(方法的參數)異常類型)
例如本例中:
execution(* com.edu.aop.hello.A.*())
使用說明:
1)“傳回型別”、“方法名”和“方法參數”是必選項,其他各項是可選項;
2)在“切入點運算式”中可以使用萬用字元。
常用萬用字元:
“*”代表不包含“.”的字串,若要包含“.”,必須使用轉義符號“\.”;
“..”代表任意數量任意類型的參數。
3)名稱模式比對的是方法名。可以用*萬用字元表示匹配所有方法名。
4)若在同一包中,可省略包名,直接給出類(介面)名稱;
5)切入點運算式可以通過操作符“&&”、“||”、“!”進行合并運算,形成一個新的切入點運算式。
例:
execution(* com.edu.aop.hello.A.*())||execution(* *.add(..))
參考書籍:《Java EE架構開發技術與案例教程》