《AOP挖掘記》概念介紹及原理初探(一)

stone哥發表於2018-09-19

AOP 的基本概念

AOP 是 Aspect-Oriented programming 的縮寫,中文翻譯為面向切面程式設計,它和 OOP 一樣是一種程式設計思想。

AOP 把軟體系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處都基本相似。比如許可權認證、日誌、事務處理。AOP 的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。通俗的講就是將應用程式中的業務邏輯同對其提供支援的通用服務進行分離,AOP 可以說是 OOP 的補充和完善。
OOP 的基本特性.png

使用 OOP 的好處是可以設計出低耦合的系統,使系統更加靈活、更加易於維護,但同時也增加了程式碼的重複性。比如,我們要列印類中每個方法的出入參。按物件導向的程式設計思想,就必須在類的每方法中都加入日誌列印功能。如下左圖所示:

此時引入 AOP 的程式設計思想,將日誌列印功能(切面),動態的切入到類中每個方法的前後(切點),無需改動原有程式碼,便可改變其原有的行為。如下右圖所示:
OOP + AOP 日誌例子.png

除此之外,使用 AOP 的程式設計思想,還能降低模組的耦合度、增強程式碼的複用性、使系統更容易擴充套件。

AOP 的相關術語

AOP 的相關術語.png

以上 AOP 術語在整個環節中的具體位置,如下圖所示:
AOP 整個環節.png

AOP 的使用場景

AOP 的使用場景.png

AOP 的實現原理

在瞭解了 AOP 的基本特徵、相關術語、使用場景之後,對設計模式有一定了解的朋友,一定已經猜到 AOP 實際上是基於代理模式實現的。

代理模式是常用的 Java 設計模式,他的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理訊息、過濾訊息、把訊息轉發給委託類,以及事後處理訊息等。代理類與委託類之間通常會存在關聯關係,一個代理類的物件與一個委託類的物件關聯,代理類的物件本身並不真正實現服務,而是通過呼叫委託類的物件的相關方法,來提供特定的服務。如以下類圖所示:
代理模式.png

按照代理的建立時期,代理類可以分為兩種。

  • 靜態代理:由程式設計師建立或特定工具自動生成原始碼,再對其編譯。在程式執行前,代理類的.class檔案就已經存在了。
  • 動態代理:在程式執行時,運用反射機制動態建立而成。

AOP 的具體實現

上面有講過,切面織入的方式有3種,分別是:

  • 執行時織入(Runtime wearing):是指採用 JDK 動態代理或 CGLIB 工具進行切面的織入。
  • 編譯期織入(Compile time wearing):是指在 Java 編譯期,採用特殊的編譯器,將切面織入到 Java 類中。
  • 類載入期織入(Classload time wearing):是指通過特殊的類載入器,在類位元組碼載入到 JVM 時織入切面。

我們最常用的 Spring AOP 是採用執行時織入(Runtime wearing),它是基於動態代理的實現的。如果需要代理的物件,實現了某個介面,那麼 Spring AOP 會使用 JDK Proxy 去建立代理物件,而對於沒有實現介面的物件,Spring AOP 會使用 CGLIB 生成一個被代理物件的子類,如下圖所示:
Spring AOP.jpg

Spring AOP 的目的並不是為了提供最完整的 AOP 實現,而是為了要幫助解決企業應用中的常見問題,提供一個 AOP 實現與 Spring IOC 之間的緊密整合。如果你計劃在 Spring Beans 之上將橫切關注點模組化,那麼 Spring AOP 是你的首選。但如果你用的是普通的 Java 物件而不是 Spring beans,又或者是想支援全部的 Pointcut 型別,那麼你就需要引入更完備的 AOP 框架 AspectJ 了。

AspectJ 是一個面向切面的框架,它無縫擴充套件了 Java 語言,它有一個專門的編譯器用來生成遵守 Java 位元組編碼規範的 Class 檔案。它採用編譯期織入(Compile time wearing)和類載入期織入(Classload time wearing),它是基於靜態代理的實現的,是語言級的 AOP 實現,提供了完備的 AOP 支援。編譯期織入過程如下圖所示:
AspectJ AOP.png

除了 Spring AOP 和 AspectJ 之外,還有很多開源框架也包含了 AOP 的實現,大家只要明白了其實現原理,就可以舉一反三,下次我會帶著大家徒手實現簡單的 AOP 框架,敬請期待。

系列文章

《AOP 挖掘記》徒手實現 AOP 框架(二)(未完成)
《AOP 挖掘記》Spring AOP 原理解析(三)(未完成)
《AOP 挖掘記》AspectJ AOP 原理解析(四)(未完成)


相關文章