第3章 創建切面

第3章 創建切面   文章指數:0  CSDN Blog推出文章指數概念,文章指數是對Blog文章綜合評分後推算出的,綜合評分項分別是該文章的點擊量,回覆次數,被網摘收錄數量,文章長度和文章類型;滿分100,每月更新一次。
1、AOP介紹
大多數AOP定義都是關於如何使交叉業務模塊化
應用系統分成多個模塊,每個模塊的主要業務是爲它的特殊領域提供服務。然而,每個模塊也需要一些相似的輔助功能,如安全和事務管理。重要通用功能的常用面向對象技術是使用繼承和委託模式。但由於基礎類在系統中到處使用,使用繼承會引起脆弱的繼承關係,委託模式比較笨拙,依然需要重複調用委託對象
在多數情況下,AOP是一種簡單的替代方法。使用AOP,在一個地方定義通用功能,只是聲明式定義何時何地使用這些功能,而不需要再需要新功能的地方修改代碼。交叉業務現在可以被模塊化到特定對象切面中。這樣做,有兩個好處:第一,現在每個業務邏輯放在一個地方,而不是分散到代碼的各個角落。第二,服務模塊更加清晰,因爲他們只包含他們的核心功能,輔助功能轉移到切面中
1.1、定義AOP術語
切面:要實現的交叉功能
連接點:連接點是應用程序執行過程中插入切面的地點,這個地點可以是方法調用,異常拋出。切面代碼在這些地方插入到你的應用流程中,添加新的功能
通知:切面的實際實現
切入點:定義了通知應該應用在哪些連接點。通過指定類名和方法名,或者匹配類名和方法名式樣的正則表達式來指定切入點
引入:引入允許爲已存在的類添加新的方法和屬性
目標對象:目標對象是被通知對象。如果沒有AOP,這個類就必須要包含它的主要邏輯以及其他交叉業務邏輯。有了AOP,目標對象就可以全身心的關注主要業務,忘記應用其上的通知
代理:代理是將通知應用到目標對象後創建的對象。對於客戶對象來說,目標對象和代理對象是一樣的,應用程序的其他部分不用爲了支持代理對象而改變
織入:織入是將切面應用到目標對象從而創建一個新的代理對象的過程。切面在指定接入點被織入目標對象。織入發生在目標對象生命週期的多個點上:
編譯期:切面在目標對象編譯時織入
類轉載期:切面在目標對象被載入到JVM中時織入
運行期:切面在應用系統運行時織入。通常,AOP容器將在織入切面的時候動態生成委託目標對象的代理對象
1.2、Spring的AOP實現
在Spring中,所有的切入點都以Java類的形式編寫
切入點通常編寫在Spring的配置文件中
Spring在運行期間創建代理對象
Spring有兩種代理創建方式:
如果目標對象實現了一個接口,Spring使用JDK的Proxy類創建代理。這個類讓Spring動態產生一個新的類,它實現了所需的接口,織入了通知,並且代理對目標對象的所有請求
如果目標對象沒有實現任何接口,Spring使用CGLIB庫生成目標對象的子類。在創建這個子類的時候,Spring將通知織入,並且將目標對象的調用委託給這個子類
Spring只支持方法連接點
2、創建通知
通知包含了切面的邏輯。創建一個通知對象的時候,是在編寫實現交叉功能的代碼。Spring的連接點模型是建立在方法攔截上。編寫的Spring通知會在方法調用周圍的各個地方織入系統中。因爲Spring在方法執行的多個地方織入通知,所以有多種通知類型
2.1、前置通知
擴展MethodBeforeAdvice接口
public interface MethodBeforeAdvice{
    void before(Method method,Object[] args,Object target)
    throws Throwable
}
這個接口爲我們提供了獲得目標方法、參數以及目標對象的機會。方法返回後目標方法將被調用
ProxyFactoryBean類是在BeanFactory和ApplicationContext中用來顯式創建代理類對象的中心類。給它提供一個要實現的接口、一個要代理的目標對象、一個要織入的通知,它將創建一個嶄新的代理對象
2.2、後置通知
實現MethodAfterAdvice接口
2.3、環繞通知
MethodInterceptor接口提供了在一個通知對象中實現前置通知和後置通知的能力
2.4、異常通知
ThrowsAdvice接口定義在異常發生時該有什麼動作
2.5、引入通知
引入通知給目標對象添加新的方法以及屬性
3、定義切入點
切入點決定了一個特定類的特定方法是否滿足一條特定規則。如果一個方法確實符合,通知就應用到該方法上
3.1、在Spring中定義切入點
Spring根據需要織入通知的類和方法來定義切入點。通知是根據他們的特性織入目標類和方法的,如類名和方法簽名
Spring切入點框架的核心接口是Pointcut接口
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
ClassFilter決定一個類是否符合通知的要求
public interface ClassFilter {
boolean matches(Class clazz);
}
實現這個接口的類決定了以參數形式傳入進來的類是否應該被通知
MethodMatcher接口通過方法過濾切面
public interface MethodMatcher {
boolean matches(Method m, Class targetClass);
public boolean isRuntime();
public boolean matches(Method m, Class target, Object[] args);
}
matches(Method m, Class targetClass)方法根據目標類和方法決定一個方法是否給被通知,因爲可以靜態的判斷,所以可以在AOP代理被創建的時候調用一次這個方法。這個方法的結果最終決定了通知是否被織入
如果matches(Method m, Class targetClass)方法返回ture,isRuntime()用來決定MethodMatcher的類型,有兩種類型:靜態和動態。靜態切入點的意思是通知總是被執行。如果一個切入點是靜態的,isRuntime()方法應該返回false。動態切入點根據運行時方法的參數值決定通知是否需要執行。如果一個切入點是動態的,isRuntime()方法應該返回ture。isRuntime()方法在代理類創建時調用一次
對於動態切入點,目標對象方法每次被調用的時候,matches(Method m, Class target, Object[] args)方法被調用
3.2、理解Advisor
大多數切面是由定義切面行爲的通知和定義切面和什麼地方執行的切入點如何而成的
大多數Spring自帶的切入點都有一個對應的PointcutAdvisor,方便在一個地方定義切入點和通知
    public interface PointcutAdvisor {
Pointcut getPointcut();
Advice getAdvice();
}
4、創建引入
其他類型通知是在方法調用的周圍織入到不同的連接點。而引入則是影響整個類。他們通過給需要消息的類添加方法和屬性來實現。也就是說,用一個已經存在的類讓它實現另外的接口,維持另外的狀態
4.1、實現IntroductionInterceptor
Spring通過特殊的方法攔截器接口IntroductionMethodInterceptor接口來實現引入
引入通知爲對象添加了新的接口和新的屬性
5、使用ProxyFactoryBean
ProxyFactoryBean創建代理對象
6、自動代理
對於小型應用系統,可以使用ProxyFactoryBean創建代理對象,因爲沒有許多類需要通知
Spring有一種自動代理機制,可以讓容器產生代理
7、小結
AOP是面向對象編程的一個有力補充。有了切面,可以將從前分散在應用系統中的功能重組變成可重用組件。現在可以採用聲明方式或編碼方式來定義這些功能應用到哪裏,以及如何使用。這樣減少了重複代碼,並且將代碼專注於它的主要功能上
Spring提供了一個AOP框架,能夠將切面添加到方法執行的周圍。可以在方法調用的前面,後面以及周圍織入通知,也可以爲異常處理添加定製行爲
使用Spring的切入點機制定義在哪裏將通知織入應用系統。一般會使用Spring預定義的靜態切入點
除了在方法周圍添加通知之外,引用能夠爲應用對象添加新的方法和屬性。引用可以動態創建複合對象,給予多繼承一樣的能力
Spring提供了多種方便的創建代理對象的方法,使用ProxyFactoryBean,可以完全掌握代理的創建。當使用自動代理時,也有許多靈活的控制方法
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章