1. 程式人生 > >從零開始的實習——Spring——AOP初識

從零開始的實習——Spring——AOP初識

從OOP到AOP

從過程化的程式設計到面向物件程式設計OOP,我們一直在找到更加完美的開發方法。當OOP/OOSD(Object-Oriented Software Development)被提出來,以取代過去的面向過程的程式設計方法時,或許那時候的人們認為這是一直所追求的那顆“銀彈”。但是,不得不承認的是,即使是OOP,依然不能很好的解決所有問題。 使用OO,我們可以對業務需求等普通關注點進行很好的抽象和封裝,但是對於系統需求而言,情況卻有所不同。 對於CREDIT專案為例,它是一個有關貸款業務的管理系統。從業務角度來說,該系統提供了顧客貸款申請、顧客資訊管理、貸款資訊管理等功能,這些都是普通的業務需求

。 不過,在開發中為了除錯,或者進入生產環境後為了對系統進行監控,我們需要為這些業務需求的實現物件新增日誌記錄功能。這些則屬於系統需求的範圍在這裡插入圖片描述 對於普通的業務關注點,OOP可以很好的對其分解並模組化,但是卻無法避免系統需求的實現在系統中各處產生的散落問題。 這時就引入了AOP: AOP全稱Aspect-Oriented Programming,即面向切片程式設計。使用AOP,我們可以對類似於Logging和Security等系統需求進行模組化的組織,簡化系統需求與實現之間的對比關係,進而使得整個系統的實現更具模組化。 Aspect之於AOP就像Class之於OOP 在這裡插入圖片描述 橫向切片,縱向模組。 這是兩個不同的空間,通過OOP的空間結合AOP的空間就可以構建出一個完美的系統。 ** AOP的尷尬** 不過,由於當時的技術缺陷,完美可以構造出AOP的一片一片的切片,卻無法構建出AOP獨有的空間。也就是AOP的實現需要寄生在OOP的主權領土中。

AOP走向現實

AOP是一種歷年,要實現這種理念也需要一種現實的方式,就像OOP需要相應的語言支援一樣。 我們把實現AOP的語言叫做AOL。AOL可以與系統實現語言相同,比如OOP用的java,那麼AOL也可以為java。但是也可以不同,比如AspectJ是擴充套件自Java的一種AOL。 靜態AOP 也就是第一代AOP,以最初的AspectJ為代表,其特點是橫切關注點以Aspect形式實現後,會通過特定點一起,將實現後的Aspect編譯並織入到系統的靜態類中。比如AspectJ會使用ajc編譯器將各個Aspect以Java位元組碼的形式編譯到系統的各個功能模組中,以達到融合Aspect和Class的目的。 靜態AOP的優點就是:直接以Java位元組碼的形式編譯到Java類中,Java虛擬機器可以像通常一樣載入Java類執行。 缺點就是:靈活性不夠,如果橫切關注點需要改變織入系統的位置,就需要重新修改Aspect定義檔案,然後使用編譯器重新Aspect並重新織入到系統中。 動態AOP

也是第二代AOP。這代AOP大都通過Java語言提供的各種動態特性來實現Aspect織入到當前系統的過程,比如JBoss AOP,Spring AOP以及Nanning等框架。 第二代AOP的AOL大多采用Java實現,所以很容易開發和整合,Aspect與Class一樣最終以Class身份作為系統的一等公民存在,與靜態AOP最大的不同就是,AOP的織入過程是系統執行開始之後進行的,而不是預先編譯到系統類中,而且織入資訊大都由外部XML檔案格式儲存,可以很靈活的調整織入點和修改織入邏輯。缺點就是,難免會對系統的效能造成一定的損失,不過這個損失是可以容忍的。

Java平臺上的AOP實現機制

動態代理 可以在執行期間,為相應的介面動態生成代理物件。 動態位元組碼增強 我們知道,java虛擬機器載入的class檔案都是符合一定規範的,這樣程式執行就不會有問題。通常的class檔案都是從Java原始碼檔案使用javac編譯器編譯成的,但是隻要符合java class規範,我們也可以使用ASM或者CGLIB等java工具庫,在程式執行期間,動態構建位元組碼的class檔案。 自定義類載入器 所有java程式的class都要通過相應的類載入器(ClassLoader)載入到Java虛擬機器之後才可以執行。預設的類載入器會讀取class位元組碼檔案,然後按照class位元組碼規範,解析並載入這些class檔案到虛擬機器執行,如果我們能夠在這個class檔案載入到虛擬機器執行期間,橫切邏輯織入到class檔案的話,是不是就完成了AOP和OOP的融合呢? AOL拓展 採用拓展的AOL,在AOP概念的表述上頗具實力。