Spring AOP 詳解

俺就不起網名發表於2018-09-02

目錄

 

一、相關術語

1、連線點(Joinpoint)

2、切點(Pointcut)

3、通知(Advice)

4、目標物件(Target)

5、引介(Introduction)

6、織入(Weaving)

7、代理(Proxy)

8、切面(Aspect)

二、動態代理

三、Spring AOP 增強介紹

四、建立切面

五、Spring自動建立代理

六、AOP無法增強疑難問題剖析

七、總結


一、相關術語

1、連線點(Joinpoint)

程式執行的某個特定位置:如類開始初始化前、類初始化後、類某個方法呼叫前、呼叫後、方法丟擲異常後。一個類或一段程式程式碼擁有一些具有邊界性質的特定點,這些點中的特定點就稱為“連線點”。Spring僅支援方法的連線點,即僅能在方法呼叫前、方法呼叫後、方法丟擲異常時以及方法呼叫前後這些程式執行點織入增強。連線點由兩個資訊確定:第一是用方法表示的程式執行點;第二是用相對點表示的方位。如在Test.foo()方法執行前的連線點,執行點為Test.foo(),方位為該方法執行前的位置。

2、切點(Pointcut)

每個程式類都擁有多個連線點,如一個擁有兩個方法的類,這兩個方法都是連線點,即連線點是程式類中客觀存在的事物。AOP通過“切點”定位特定的連線點。連線點相當於資料庫中的記錄,而切點相當於查詢條件。切點和連線點不是一對一的關係,一個切點可以匹配多個連線點。

3、通知(Advice)

也叫增強,是織入到目標類連線點上的一段程式程式碼,在Spring中,增強除用於描述一段程式程式碼外,還擁有另一個和連線點相關的資訊,這便是執行點的方位。結合執行點方位資訊和切點資訊,我們就可以找到特定的連線點。

4、目標物件(Target)

增強邏輯的織入目標類。如果沒有AOP,目標業務類需要自己實現所有邏輯,而在AOP的幫助下,目標業務類只實現那些非橫切邏輯的程式邏輯,而效能監視和事務管理等這些橫切邏輯則可以使用AOP動態織入到特定的連線點上。

5、引介(Introduction)

引介是一種特殊的增強,它為類新增一些屬性和方法。這樣,即使一個業務類原本沒有實現某個介面,通過AOP的引介功能,我們可以動態地為該業務類新增介面的實現邏輯,讓業務類成為這個介面的實現類。    

6、織入(Weaving)

織入是將增強(通知)新增到目標類具體連線點上的過程。AOP像一臺織布機,將目標類、增強或引介通過AOP這臺織布機天衣無縫地編織到一起。根據不同的實現技術,AOP有三種織入的方式:

    a、編譯期織入,這要求使用特殊的Java編譯器。
    b、類裝載期織入,這要求使用特殊的類裝載器。
    c、動態代理織入,在執行期為目標類新增增強生成子類的方式。
    Spring採用動態代理織入,而AspectJ採用編譯期織入和類裝載期織入。

7、代理(Proxy)

 

 一個類被AOP織入增強後,就產出了一個結果類,它是融合了原類和增強邏輯的代理類。根據不同的代理方式,代理類既可能是和原類具有相同介面的類,也可能就是原類的子類,所以我們可以採用呼叫原類相同的方式呼叫代理類。

8、切面(Aspect)

切面由切點和增強(引介)組成,它既包括了橫切邏輯的定義,也包括了連線點的定義,Spring AOP就是負責實施切面的框架,它將切面所定義的橫切邏輯織入到切面所指定的連線點中。

二、動態代理

 

關於動態代理的詳細介紹見此文章

我們雖然通過動態代理可以實現橫切邏輯的動態織入(如加日誌),但這種實現方式存在三個明顯需要改進的地方: 

1)目標類的所有方法都新增了效能監視橫切邏輯,但有時我們可能只希望對業務類中的某些特定方法新增橫切邏輯; 
2)我們通過硬編碼的方式指定了織入橫切邏輯的織入點,即在目標類業務方法的開始和結束前織入程式碼; 
3)我們手工編寫代理例項的建立過程,為不同類建立代理時,需要分別編寫相應的建立程式碼,無法做到通用。 

以上三個問題,在AOP中佔用重要的地位,因為Spring AOP的主要工作就是圍繞以上三點展開:

1、Spring AOP通過Pointcut(切點)指定在哪些類的哪些方法上織入橫切邏輯;
2、通過Advice(增強)描述橫切邏輯和方法的具體織入點(方法前、方法後、方法的兩端等);
3、Spring通過Advisor(切面)將Pointcut和Advice兩者組裝起來。有了Advisor的資訊,Spring就可以利用JDK或CGLib的動態代理技術採用統一的方式為目標Bean建立織入切面的代理物件了。 

 

三、Spring AOP 增強介紹

 

關於Spring AOP 增強見此文章

四、建立切面

關於Spring AOP 建立切面見此文章

五、Spring自動建立代理

關於Spring自動建立代理見此文章

六、AOP無法增強疑難問題剖析

Spring註解無法呼叫自身的方法原因

七、總結

1、AOP是OOP的延伸,它為程式開發提供了一個嶄新的思考角度,可以將任意性的橫切邏輯抽取到同一模組中,只有通過OOP的縱向抽象和AOP的橫向抽取,程式才可以真正解決重複性程式碼的問題;

2、 Spring採用JDK動態代理和CGLib動態代理的技術在執行期織入增強,左移使用者不需要裝備特殊的編譯器或類裝載器就可以使用AOP的功能,要使用JDK動態代理,目標類必須事先介面,而CGLib不對類做任何限制,通過動態生成目標子類的方式提供代理。JDK在建立代理物件時效能高於CGLib,而生成的代理物件的執行效能卻比CGLib低,如果是singleton的代理,推薦使用CGLib動態代理;

3、Spring只能在方法級別上織入增強,Spring提供了4中型別的方法增強,分別是前置增強後置增強環繞增強和異常丟擲增強此外還有引介增強,引介增強是類級別的它為目標類織入新的介面實現。廣義上來看,增強其實就是一種最簡單的切面,他既包括橫切程式碼也包括切點資訊,只不過他的切點只是簡單地方法相對位置的資訊,所以增強一般需要和切點聯合才可以表示一個更具有實用性的切面;

4、切面是增強和切點的聯合體,使用者很方便的通過Spring提供的ProxyBeanFactory將切面織入不同的目標類中。當然,為每一個目標類手工配置一個切面是比較繁瑣的,Spring利用BeanPostProcessor 可干涉Bean生命週期的機制,提供了一些可以自動建立代理,織入切面的自動代理建立器,其中DefaultAdivsorAutoProxyCreator是功能強大的自動代理建立器,它可以將容器中所有的Advisor自動織入目標Bean中。

相關文章