一、面向切面編程提供了另外一種角度來思考程序結構,通過這種方式來彌補面向對象(OOP)的不足。除了classes(類)以外,AOP提供了切面!切面對關注點進行模塊化,例如橫切多個類型和對象的事物管理。這個關注點術語通常稱作橫切關注點。
AOP是Spring框架的另一個重要特徵。AOP把一個業務流程分成幾個部分,例如權限檢查、業務處理、日誌記錄,每個部分單獨處理,然後把他們組裝成完整的業務流程。每個部分都被稱爲切面(Aspect)或者關注點。
Spring的一個關鍵組件就是AOP框架,儘管Spring IOC 不依賴於AOP,這意味着你可以自由選擇是否使用AOP,AOP提供強大的中間件解決方案,這使得Spring IOC容器更加完美!
Spring中使用的AOP:允許用戶自定義切面,用AOP來完善OOP的使用。
1.切面(aspect):一個關注點的模塊化,這個關注點可能會橫切多個對象。切面(用@Aspect註解的類)和其他類一樣有方法和字段定義。他們可能包含切入點、通知和引用申明。
Spring2.0引入一種更加簡單也更加強大的方式來自定義切面,用戶可以選擇使用基於模式(schema-based)的方式或者使用@AspectJ註釋!這兩種風格都完全支持通知(Advice)類型和AspectJ的切入點語言!
下面是application context中一個常見的bean定義,這個bean指向一個使用了@Aspect註解的bean類
<bean id="myaspect" class="org.xyz..MyAspect " >
</bean>
下面是MyAspect類定義,使用了org.aspectj.lang.annotation.Aspect註解。
package AOP.org.xyz;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class MyAspect {
}
申明一個切面,有了schema的支持,切面就和常規的Java對象一樣被定義成application context中的一個bean.
<aop:config>
<aop:aspect id="myAspect" ref="aBean">
</aop:config>
<bean id="aBean" calss="AOP.org.xyz.MyAspect" />
</bean>
2.切入點(Pointcut):匹配連接點的斷言,通知和一個切入點表達式關聯,並在滿足這個切入點的連接點上運行(例如執行某個特定名稱和方法是)。
切入點決定了連接點的關注內容(是連接點的集合),使得我們可以控制關注點什麼時候執行。Spring AOP只支持Spring bean 方法執行連接點。所以你可以把切入點看做是匹配Spring bean上方法的執行。
一個切入點聲明有兩個部分:一個包含名字和任意參數的簽名,還有一個切入點表達式,該表達式決定了我們關注那個方法的執行。
@Pointcut("execution(*transfer(..))") //切入點表達式
private void anyOldTransfer(){ //切入點簽名
}
這個切入點將匹配任何名爲transfer的方法執行。
切入點制定者的支持 Spring AOP支持在切入點表達式中使用如下的AspectJ切入點制定者
-executon-匹配方法執行的連接點,這是你將用到Spring的最主要的切入點指定者。
-within-限定匹配特定類型的連接點
-this-限定匹配特定的連接點,其中 bean reference(Spring AOP代理)是指定類型的實例。
-target-限定匹配特定的連接點,其中目標對象(被代理的application object)是指定類型的實例。
Spring AOP限定了連接點必須是方法執行級別的,pointcut designators的討論中也給出了一個定義,這個定義和AspectJ編程指南中定義的相比更加狹窄。
Spring AOP是一個基於代理的系統,並且嚴格區分代理對象本身(對應於this)和背後的目標對象(對應於target).
合併切入點表達式:切入點表達式可以通過:‘&&’、‘||’、‘!’來合併,還可以通過名字來指向切入點表達式。
以下例子展示了三個切入點表達式:anyPublicOperation(在一個方法執行連接點代表了任意public方法的執行匹配),isTrading(在一個代表了在交易模塊中的任意方法執行時匹配)和tradingOperation(在一個代表了交易模塊中任意公共方法執行是匹配)。
就上所示,從更小的命名組件來構建更加複雜的切入點表達式是一種最佳實踐。當用名字來指定切入點時使用的是常見的Java成員可視性訪問規則。
共享常見的切入點定義:在開發企業級應用的時候,你通常想要從幾個切面來參考模塊化的應用和特定操作的集合。我們推薦定義一個切面來捕捉常見的切入點表達式,一個典型的切面看起來像下面這樣。
示例中的切入點定義了一個你可以在任何需要切入點的表達式的地方可引用的切面。 比如可以時使service層事務化。
3.連接點(Joinpoint)在程序執行過程中某個特定的點,比如是方法調用的時候或者異常處理的時候。在Spring AOP中一個連接點總是代表一個方法的執行。通過聲明org.aspect.lang.JoinPoint類型的參數可以通知的主體部分獲得連接點信息。。
4.通知(Advice):在切面的某個特定的連接點(joinpoint)上執行的動作,通知有各種類型,其中包括“aound”,"before“,"after"等通知。
Spring的AOP以攔截器做通知的模型,執行是並維護一個以連接點爲中心的攔截器棧。
@Before("fooException()")、@AfterReturning("fooException()")
5.引入(Introduction)(也被稱爲內部類型聲明):聲明額外的方法或者某個類型的字段,Spring允許引入新的接口(以及一個對應的實現)到任何被代理的對象。
引入使得一個切面可以定義被通知對象實現一個給定的接口,並且可以代表那些對象提供具體實現。
6.目標對象(Target Object):被一個或多個切面所通知(advice)的對象,也可以叫被通知對象。既然Spring AOP是通過運行時代理實現的。這個對象永遠是一個被代理的對象。
7.AOP代理(AOP Proxy):AOP框架創建的對象,來實現切面契約(包括通知方法執行等功能)。
在Spring 中,AOP代理可以是JDK動態代理或者CGLIB代理。
8.織入(Weaving):把切面連接到其他的應用程序或者對象上,並創建一個被通知的對象。這些可在編譯時、類加載時和運行時完成。Spring和其他JAVA AOP一樣在運行時織入。
二、Spring中AOP的兩種配置方式。
1.基於配置文件的配置方式。
創建一個JAVA文件,並指定一個用於執行攔截的方法,該方法可以有0個或者多個參數,在Spring配置文件中配置該類爲一個Bean.
使用<aop:config>以及<aop:aspect>、<aop:adviser>進行配置。
2.基於@AspectJ標籤的配置方式。
1.在配置文件中加<aop:aspectj-autoproxy/>註解。
2.創建一個JAVA文件,使用@Aspect註解修飾該類。
3.創建一個方法,使用@Before,@After,@Around等進行修飾,在註解中寫入切入點的表達式。
上述JAVA類創建好之後需要在Spring容器中進行聲明。可以在配置文件中定義<bean:/>節點,也可以使用@Component組件進行裝飾。