Spring-AOP【總結】
概念
AOP(Aspect Oriented Programming),即面向切面程式設計(也叫面向方面程式設計,面向方法程式設計)。其主要作用是,在不修改原始碼的情況下給某個或者一組操作新增額外的功能。像日誌記錄,事務處理,許可權控制等功能,都可以用AOP來“優雅”地實現,使這些額外功能和真正的業務邏輯分離開來,軟體的結構將更加清晰。AOP是OOP的一個強有力的補充。
術語
AOP的術語不太直觀,Spring文件中也沒有給一個確切的定義,所以重在理解。
-
Join Point: Spring AOP中,join point就是一個方法。(通俗來講就是起作用的那個方法)。
-
Pointcut: 用來指定join point(通俗來講就是描述的一組符合某個條件的join point)。通常使用pointcut表示式來限定joint point,Spring預設使用AspectJ pointcut expression language。
-
Advice: 在join point上特定的時刻執行的操作,Advice有幾種不同型別,下文將會討論(通俗地來講就是起作用的內容和時間點)。
-
Introduction:給物件增加方法或者屬性。
-
Target object: Advice起作用的那個物件。
-
AOP proxy: 為實現AOP所生成的代理。在Spring中有兩種方式生成代理:JDK代理和CGLIB代理。
-
Aspect: 組合了Pointcut與Advice,在Spring中有時候也稱為Advisor。某些資料說Advisor是一種特殊的Aspect,其區別是Advisor只能包含一對pointcut和advice,但是aspect可以包含多對。AOP中的aspect可以類比於OOP中的class。
-
Weaving:將Advice織入join point的這個過程。
Advice的型別
-
Before advice: 執行在join point之前的advice,但是它不能阻止joint point的執行流程,除非丟擲了一個異常(exception)。
-
After returning advice: 執行在join point這個方法返回之後的advice。
-
After throwing advice: 執行在join point丟擲異常之後的advice。
-
After(finally) advice: 執行在join point返回之後或者丟擲異常之後的advice,通常用來釋放所使用的資源。
-
Around advice: 執行在join point這個方法執行之前與之後的advice。
兩種代理
Spring AOP是基於代理機制的。上文說到,Spring AOP通過JDK Proxy和CGLIB Proxy兩種方法實現代理。
如果target object沒有實現任何介面,那麼Spring將使用CGLIB來實現代理。CGLIB是一個開源專案,它是一個強大的,高效能,高質量的Code生成類庫,它可以在執行期擴充套件Java類與實現Java介面。
如果target object實現了一個以上的介面,那麼Spring將使用JDK Proxy來實現代理,因為Spring預設使用的就是JDK Proxy,並且JDK Proxy是基於介面的。這也是Spring提倡的面向介面程式設計。當然,你也可以強制使用CGLIB來進行代理,但是這樣可能會造成效能上的下降。
Pointcut expression
Pointcut通過pointcut expression來描述,有若干種限定詞。由於Pointcut的定義在Spring文件7.2.3 Declaring a pointcut中寫得比較詳細,所以在此不再贅述。
Spring AOP的使用
我們可以通過三種方式來使用Spring AOP,它們分別是:@Aspect-based(Annotation),Schema-based(XML),以及底層的Spring AOP API。
@Aspect-based (Annotation)
Annotaion是最常用的方式。
配置
首先,我們應該在配置檔案中增加對Annotation的支援。
假設我們的配置檔案是classpath下的applicationContext.xml,新增如下片段:
1
|
|
業務邏輯類
假設我們有一個UserManager類,這個類負責處理業務邏輯。類的定義如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
這是一個很普通的Java物件,看不出任何Spring AOP的痕跡,這也是Spring低侵入式設計的體現。
切面(Aspect)類
為了給業務邏輯增加額外功能,我們需要定義一個切面類,切面類裡包含了pointcut和advice。假設我們的切面類是ExampleAspect,程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|