(二)Spring AOP源碼-1.概述與設計原理-02設計原理

本文已收錄於【Spring源碼札記專欄】

關聯文章:
(二)Spring AOP源碼-1.概述與設計原理-01概述
(二)Spring AOP源碼-1.概述與設計原理-02設計原理

AOP實現的關鍵在於自動創建AOP代理,AOP代理可分爲靜態代理和動態代理。

靜態代理與動態代理

靜態代理主要在虛擬機啓動時通過改變目標對象字節碼的方式完成對目標對象的增強。以靜態代理爲基礎實現的AOP技術的代表爲AspectJ。AspectJ在編譯期間生成代理對象,因此也稱爲編譯時增強。

動態代理不會去修改字節碼,而是在運行時在內存中臨時生成AOP對象。這個AOP對象包含了目標對象的全部方法,並且在特定的切點做了增強處理,並回調原對象的方法。以動態代理爲基礎實現的AOP技術則以Spring AOP爲代表。Spring AOP的源碼中用到了兩種動態代理:JDK動態代理和CGLIB動態代理。

AspectJ

AspectJ 是一個基於Java語言的AOP框架,提供了強大的AOP功能,其他很多AOP框架都借鑑或採納其中的一些思想。

JDK動態代理和CGLIB動態代理

JDK動態代理通過反射來接收被代理的類,並且要求被代理的類必須實現一個接口。JDK動態代理的核心是InvocationHandler接口和Proxy類。如果被代理的類沒有實現接口,那麼Spring AOP會選擇使用CGLIB來。

CGLIB(Code Generation Library),是一個代碼生成的類庫,可以在運行時動態的生成某個類的子類。CGLIB動態代理底層則是藉助ASM(Java字節碼生成框架)來實現的。CGLIB實現的基礎是繼承,因此如果某個類被標記爲final,那麼它是無法使用CGLIB做動態代理的。

AOP默認使用哪種動態代理方式

默認使用JDK動態代理來創建AOP代理。當需要代理的類沒有實現接口的時候,Spring會使用CGLIB。當然,也可強制使用CGLIB。

如何強制使用CGLIB

<aop:config>裏面有一個」proxy-target-class」屬性,這個屬性值如果被設置爲true,那麼基於CGLIB動態代理將起作用。這個屬性值默認爲false。

Spring AOP設計原理

在前面的內容中,提到的最多的一個詞就是「代理」。事實上,JDK動態代理就實現了設計模式中的代理模式。關於代理模式可以參考我之前寫的一篇文章設計模式(12)-代理模式
MarkdownPhotos/master/CSDNBlogs/DesignPatterns/proxy.png 圖中的RealSubject就是被代理的類,Proxy是生成的代理類。Proxy對RealSubject的request方法進行了增強處理,即preRequest方法和afterRequest方法。