一、引言
二、AOP技術基礎 三、Java平臺AOP技術研究
四、.Net平臺AOP技術研究
2.1 AOP技術起源html
AOP技術的誕生並不算晚,早在1990年開始,來自Xerox Palo Alto Research Lab(即PARC)的研究人員就對面向對象思想的侷限性進行了分析。他們研究出了一種新的編程思想,藉助這一思想或許能夠經過減小代碼重複模塊從而幫助開發人員提升工做效率。隨着研究的逐漸深刻,AOP也逐漸發展成一套完整的程序設計思想,各類應用AOP的技術也應運而生。編程
AOP技術在Java平臺下是最早獲得應用的。就在PARC對於面向方面編程進行研究的同時,美國Northeastern University的博士生Cristina Lopes和其同事也開始了相似的思考。最終,美國國防先進技術研究計劃署(Defense Advanced Research Projects Agency即DARPA)注意到了這項工做,並提供了科研經費,鼓勵將兩者的工做成果結合起來。他們經過定義一套Java語言的擴展系統,使開發者能夠方便的進行面向方面的開發,這套擴展系統被稱爲AspectJ。以後,AspectJ在2002年被轉讓給Eclipse Foundation,從而成爲在開源社區中AOP技術的先鋒,也是目前最爲流行的AOP工具。設計模式
AspectWerkz則是基於Java的動態的、輕量級AOP框架。AspectWerkz仍然是開源社區中的產品,由BEA System提供贊助,開發者則是BEA的兩名員工Jonas Bonér和Alexandre Vasseur。最近版本是AspectWerkz 2.0。2005年1月,AspectJ和AspectWerkz達成協議,贊成將兩者的成果綜合到一塊兒,取其精華建立一個單一的工具。他們合做的第一個發佈版本爲AspectJ 5,它擴展了AspectJ語言,以支持基於Annotation開發風格而又支持相似AspectJ代碼風格。AspectJ 5也爲Java 5的語言特性提供徹底的AOP支持。安全
在Java陣營中,商用軟件製造商JBoss在其2004年推出的JBoss 4.0中,引入了AOP框架和組件。在JBoss 4.0中,用戶能夠在JBoss應用服務器外部單獨使用JBoss AOP,該版本爲JBoss AOP 1.0,是在2004年10月發佈的。在2005年,JBoss AOP框架又發佈了1.3.0版本,新版本對加載期織入(Weev)和切點(point cut)匹配的性能作了很大的優化,使應用程序的啓動時間大大縮短。性能優化
做爲輕型的Framework,Spring在開發輕量級的J2EE時,應用是很是普遍的。它經過IoC模式(Inversion of Control,控制反轉模式)來實現AOP,一般被稱爲Spring AOP。在2004年,被做爲Spring框架的擴展而發佈,目前版本已更新到1.1.3。Spring AOP做爲一種非侵略性的,輕型的AOP框架,開發者無需使用預編譯器或其餘的元標籤,在Java程序中應用AOP。目前,AOP的功能徹底集成到了Spring事務管理、日誌和其餘各類特性的上下文中。服務器
在.Net的陣營中,AOP技術的應用遠不如Java陣營對AOP的關注。2005年1月,微軟發佈的Enterprise Library提供了7種不一樣的「應用程序塊(application blocks)」。有個別專家認爲,這些組件能夠被認爲是方面。但該觀點並未獲得一致的認同。事實上,在.Net平臺下,推進AOP技術發展的原動力並不是微軟,而是開源社區。雖然,微軟的技術專家們亦然聽到了在.Net Framework中增長AOP技術的羣衆呼聲,但做爲如此巨大的軟件公司,要讓它靈活地轉變戰略方向,顯然是不太現實的。正由於此,才賜予了開源社區在AOP技術的研究與探索上一個巨大的發展空間。架構
與Java陣營中的AOP技術不一樣,目前在.Net平臺下的各類AOP工具,基本上還停留在實驗室階段。但一些在技術上領先且逐漸成熟的AOP產品,也在開源社區中漸露崢嶸。這其中主要包括Aspect#,AspectDNG,Eos AOP等。app
Aspect#是基於Castle動態代理技術來實現的。Castle源於Apache Avalon項目,其目的在於實現一個輕量級的IoC容器。Aspect#於2005年6月被收錄爲Castle的其中一個子項目。它是針對CLI(.Net和Mono)實現的AOP框架,利用了反射、代理等機制。目前的Aspect#版本爲2.1.1。框架
AspectDNG目前的版本爲0.7,仍然處於beta版的階段。它的實現技術是基於rail的靜態織入。Rail屬於IL級別下的代碼織入,它自定義的一套xml格式的ILML語言,可以將原有的程序集拆散成ILML格式,以便於對靜態程序集進行修改和擴展,從而達到靜態織入的目的。由於AspectDNG是屬於IL級別下的代碼織入,所以在.Net平臺下,並不受具體的編程語言限制。編程語言
Eos AOP與AspectDNG同樣,仍然採用靜態織入的方式,但從語法定義上,它更近似於AspectJ關於AOP的實現。它擴展了C#語法,引入了aspect、introduce、before、after等關鍵字,而且提供了專用的Eos編譯器。Eos項目是於2004年9月開始啓動,2005年6月推出的0.3.3版本爲最新版本,主要的開發人員爲Hridesh Rajan和Kevin Sullivan。前者爲Virginia大學計算機系的研究生,Eos項目最初是由Hridesh Rajan提出的;然後者則爲該計算機系的副教授(Associate Professor)。因此自Eos誕生之初,就帶有濃厚的學院派特點。
從AOP技術的總體發展來看,高性能、穩定、可擴展、易用的AOP框架是其趨勢與目標。從上述對各類AOP技術的分析來看,AOP技術無疑是具備共同特色的,而各類實現技術就是圍繞着這些共性深刻與延伸。接下來,我將概要地介紹AOP的本質,以及它的技術要素。
2.2 AOP技術本質
2.2.1 技術概覽
AOP(Aspect-Oriented Programming,面向方面編程),能夠說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP引入封裝、繼承和多態性等概念來創建一種對象層次結構,用以模擬公共行爲的一個集合。當咱們須要爲分散的對象引入公共行爲的時候,OOP則顯得無能爲力。也就是說,OOP容許你定義從上到下的關係,但並不適合定義從左到右的關係。例如日誌功能。日誌代碼每每水平地散佈在全部對象層次中,而與它所散佈到的對象的核心功能毫無關係。對於其餘類型的代碼,如安全性、異常處理和透明的持續性也是如此。這種散佈在各處的無關的代碼被稱爲橫切(cross-cutting)代碼,在OOP設計中,它致使了大量代碼的重複,而不利於各個模塊的重用。
而AOP技術則偏偏相反,它利用一種稱爲「橫切」的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用模塊,並將其名爲「Aspect」,即方面。所謂「方面」,簡單地說,就是將那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任封裝起來,便於減小系統的重複代碼,下降模塊間的耦合度,並有利於將來的可操做性和可維護性。AOP表明的是一個橫向的關係,若是說「對象」是一個空心的圓柱體,其中封裝的是對象的屬性和行爲;那麼面向方面編程的方法,就彷彿一把利刃,將這些空心圓柱體剖開,以得到其內部的消息。而剖開的切面,也就是所謂的「方面」了。而後它又以巧奪天功的妙手將這些剖開的切面復原,不留痕跡。
使用「橫切」技術,AOP把軟件系統分爲兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特色是,他們常常發生在覈心關注點的多處,而各處都基本類似。好比權限認證、日誌、事務處理。Aop 的做用在於分離系統中的各類關注點,將核心關注點和橫切關注點分離開來。正如Avanade公司的高級方案構架師Adam Magee所說,AOP的核心思想就是「將應用程序中的商業邏輯同對其提供支持的通用服務進行分離。」
實現AOP的技術,主要分爲兩大類:一是採用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行爲的執行;二是採用靜態織入的方式,引入特定的語法建立「方面」,從而使得編譯器能夠在編譯期間織入有關「方面」的代碼。然而異曲同工,實現AOP的技術特性倒是相同的,分別爲:
一、join point(鏈接點):是程序執行中的一個精確執行點,例如類中的一個方法。它是一個抽象的概念,在實現AOP時,並不須要去定義一個join point。 二、point cut(切入點):本質上是一個捕獲鏈接點的結構。在AOP中,能夠定義一個point cut,來捕獲相關方法的調用。 三、advice(通知):是point cut的執行代碼,是執行「方面」的具體邏輯。 四、aspect(方面):point cut和advice結合起來就是aspect,它相似於OOP中定義的一個類,但它表明的更可能是對象間橫向的關係。 五、introduce(引入):爲對象引入附加的方法或屬性,從而達到修改對象結構的目的。有的AOP工具又將其稱爲mixin。
上述的技術特性組成了基本的AOP技術,大多數AOP工具均實現了這些技術。它們也能夠是研究AOP技術的基本術語。
2.2.2 橫切技術
「橫切」是AOP的專有名詞。它是一種蘊含強大力量的相對簡單的設計和編程技術,尤爲是用於創建鬆散耦合的、可擴展的企業系統時。橫切技術可使得AOP在一個給定的編程模型中穿越既定的職責部分(好比日誌記錄和性能優化)的操做。
若是不使用橫切技術,軟件開發是怎樣的情形呢?在傳統的程序中,因爲橫切行爲的實現是分散的,開發人員很難對這些行爲進行邏輯上的實現或更改。例如,用於日誌記錄的代碼和主要用於其它職責的代碼纏繞在一塊兒。根據所解決的問題的複雜程度和做用域的不一樣,所引發的混亂可大可小。更改一個應用程序的日誌記錄策略可能涉及數百次編輯——即便可行,這也是個使人頭疼的任務。
在AOP中,咱們將這些具備公共邏輯的,與其餘模塊的核心邏輯糾纏在一塊兒的行爲稱爲「橫切關注點(Crosscutting Concern)」,由於它跨越了給定編程模型中的典型職責界限。
2.2.2.1 橫切關注點
一個關注點(concern)就是一個特定的目的,一塊咱們感興趣的區域,一段咱們須要的邏輯行爲。從技術的角度來講,一個典型的軟件系統包含一些核心的關注點和系統級的關注點。舉個例子來講,一個信用卡處理系統的核心關注點是借貸/存入處理,而系統級的關注點則是日誌、事務完整性、受權、安全及性能問題等,許多關注點——即橫切關注點(crosscutting concerns)——會在多個模塊中出現。若是使用現有的編程方法,橫切關注點會橫越多個模塊,結果是使系統難以設計、理解、實現和演進。AOP可以比上述方法更好地分離系統關注點,從而提供模塊化的橫切關注點。
例如一個複雜的系統,它由許多關注點組合實現,如業務邏輯、性能,數據存儲、日誌和調度信息、受權、安全、線程、錯誤檢查等,還有開發過程當中的關注點,如易懂、易維護、易追查、易擴展等,圖2.1演示了由不一樣模塊實現的一批關注點組成一個系統。
圖2.1 把模塊做爲一批關注點來實現
經過對系統需求和實現的識別,咱們能夠將模塊中的這些關注點分爲:核心關注點和橫切關注點。對於核心關注點而言,一般來講,實現這些關注點的模塊是相互獨立的,他們分別完成了系統須要的商業邏輯,這些邏輯與具體的業務需求有關。而對於日誌、安全、持久化等關注點而言,他們倒是商業邏輯模塊所共同須要的,這些邏輯分佈於核心關注點的各處。在AOP中,諸如這些模塊,都稱爲橫切關注點。應用AOP的橫切技術,關鍵就是要實現對關注點的識別。
若是將整個模塊比喻爲一個圓柱體,那麼關注點識別過程能夠用三棱鏡法則來形容,穿越三棱鏡的光束(指需求),照射到圓柱體各處,得到不一樣顏色的光束,最後識別出不一樣的關注點。如圖2.2所示:
圖2.2 關注點識別:三棱鏡法則
上圖識別出來的關注點中,Business Logic屬於核心關注點,它會調用到Security,Logging,Persistence等橫切關注點。
public class BusinessLogic { public void SomeOperation() { //驗證安全性;Securtity關注點; //執行前記錄日誌;Logging關注點;
DoSomething();
//保存邏輯運算後的數據;Persistence關注點; //執行結束記錄日誌;Logging關注點; } }
AOP的目的,就是要將諸如Logging之類的橫切關注點從BusinessLogic類中分離出來。利用AOP技術,能夠對相關的橫切關注點封裝,造成單獨的「aspect」。這就保證了橫切關注點的複用。因爲BusinessLogic類中再也不包含橫切關注點的邏輯代碼,爲達到調用橫切關注點的目的,能夠利用橫切技術,截取BusinessLogic類中相關方法的消息,例如SomeOperation()方法,而後將這些「aspect」織入到該方法中。例如圖2.3:
圖2.3 將橫切關注點織入到核心關注點中
經過利用AOP技術,改變了整個系統的設計方式。在分析系統需求之初,利用AOP的思想,分離出核心關注點和橫切關注點。在實現了諸如日誌、事務管理、權限控制等橫切關注點的通用邏輯後,開發人員就能夠專一於核心關注點,將精力投入到解決企業的商業邏輯上來。同時,這些封裝好了的橫切關注點提供的功能,能夠最大限度地複用於商業邏輯的各個部分,既不須要開發人員做特殊的編碼,也不會由於修改橫切關注點的功能而影響具體的業務功能。
爲了創建鬆散耦合的、可擴展的企業系統,AOP應用到的橫切技術,一般分爲兩種類型:動態橫切和靜態橫切。
2.2.2.2 動態橫切
動態橫切是經過切入點和鏈接點在一個方面中建立行爲的過程,鏈接點能夠在執行時橫向地應用於現有對象。動態橫切一般用於幫助向對象層次中的各類方法添加日誌記錄或身份認證。在不少應用場景中,動態橫切技術基本上表明瞭AOP。
動態橫切技術的核心主要包括join point(鏈接點),point cut(切入點),advice(通知)和aspect(方面)。在前面,我已經概要地介紹了這些術語分別表明的含義。接下來,我將以一個具體的實例來進一步闡述它們在AOP動態橫切中實現的意義。
考慮一個電子商務系統,須要對訂單進行添加、刪除等管理操做。毫無疑問,在實際的應用場景中,這些行爲應與權限管理結合,只有得到受權的用戶方可以實施這些行爲。採用傳統的設計方法,其僞代碼以下: public class OrderManager { private ArrayList m_Orders; public OrderManager() { m_Orders = new ArrayList(); } public void AddOrder(Order order) { if (permissions.Verify(Permission.ADMIN)) {
m_Orders.Add(order); } }
public void RemoveOrder(Order order) { if (permissions.Verify(Permission.ADMIN)) { m_Orders.Remove(order); } } }
一樣的,在該電子商務系統中,還須要對商品進行管理,它採用了一樣的受權機制: public class ProductManager { private ArrayList m_Products; public ProductManager() { m_Products = new ArrayList(); } public void AddProduct(Product product) { if (permissions.Verify(Permission.ADMIN)) { m_Products.Add(product); } } public void RemoveProduct(Product product) { if (permissions.Verify(Permission.ADMIN)) { m_Products.Remove(product); } } }
如此以來,在整個電子商務系統中,核心業務包括訂單管理和商品管理,它們都須要相同的權限管理,如圖2.4所示:
圖2.4 電子商務系統的權限驗證明現
毫無疑問,利用AOP技術,咱們能夠分離出系統的核心關注點和橫切關注點,從橫向的角度,截取業務管理行爲的內部消息,以達到織入權限管理邏輯的目的。當執行AddOrder()等方法時,系統將驗證用戶的權限,調用橫切關注點邏輯,所以該方法即爲AOP的join point。對於電子商務系統而言,每一個須要權限驗證的方法都是一個單獨的join point。因爲權限驗證將在每一個方法執行前執行,因此對於這一系列join point,只須要定義一個point cut。當系統執行到join point處時,將根據定義去查找對應的point cut,而後執行這個橫切關注點須要實現的邏輯,即advice。而point cut和advice,就組合成了一個權限管理aspect。
圖2.5 AOP動態橫切的技術實現
因爲aspect是一個封裝的對象,咱們能夠定義這樣一個aspect: private static aspect AuthorizationAspect{……}
而後在這個aspect中定義point cut,在point cut中,定義了須要截取上下文消息的方法,例如: private pointcut authorizationExecution(): execution(public void OrderManager.AddOrder(Order)) || execution(public void OrderManager.DeleteOrder(Order)) || execution(public void ProductManager.AddProduct(Product)) || execution(public void ProductManager.DeleteProduct(Product));
因爲權限驗證是在訂單管理方法執行以前完成,所以在before advice中,定義權限檢查: before(): authorizationExecution() { if !(permissions.Verify(Permission.ADMIN)) { throw new UnauthorizedException(); } }
經過定義了這樣一個完整的aspect,當系統調用OrderManager或ProductManager的相關方法時,就觸發了point cut,而後調用相應的advice邏輯。如此以來,OrderManager和ProductManager模塊就與權限管理模塊徹底解除了依賴關係,同時也消除了傳統設計中不可避免的權限判斷的重複代碼。這對於創建一個鬆散耦合、可擴展的系統軟件是很是有利的。
2.2.2.3 靜態橫切
靜態橫切和動態橫切的區別在於它不修改一個給定對象的執行行爲。相反,它容許經過引入附加的方法字段和屬性來修改對象的結構。此外,靜態橫切能夠把擴展和實現附加到對象的基本結構中。在AOP實現中,一般將靜態橫切稱爲introduce或者mixin。
靜態橫切在AOP技術中,受到的關注相對較少。事實上,這一技術蘊含的潛力是巨大的。使用靜態橫切,架構師和設計者能用一種真正面向對象的方法有效地創建複雜系統的模型。靜態橫切容許您不用建立很深的層次結構,以一種本質上更優雅、更逼真於現實結構的方式,插入跨越整個系統的公共行爲。尤爲是當開發應用系統時,若是須要在不修改原有代碼的前提下,引入第三方產品和API庫,則靜態橫切技術將發揮巨大的做用。
舉例來講,當前已經實現了一個郵件收發系統,其中類Mail完成了收發郵件的功能。但在產品交付後,發現該系統存在缺陷,在收發郵件時,不曾實現郵件地址的驗證功能。如今,第三方產品已經提供了驗證功能的接口IValidatable: public interface IValidatable { bool ValidateAddress(); }
咱們能夠利用設計模式中的Adapter模式,來完成對第三方產品API的調用。咱們能夠定義一個新的類MailAdapter,該類實現了IValidatable接口,同時繼承了Mail類: public class MailAdapter:Mail,IValidatable { public bool ValidateAddress() { if(this.getToAddress() != null) { return true; } else { return false; } } }
經過引入MailAdapter類,原來Mail對象完成的操做,將所有被MailAdapter對象取代。然而,此種實現方式雖然能解決引入新接口的問題,但相似下面的代碼,倒是沒法編譯經過的: Mail mail = new Mail(); IValidatable validate = ((IValidatable)mail).ValidateAddress();
必須將第一行代碼做以下修改: Mail mail = new MailAdapter();
利用AOP的靜態橫切技術,能夠將IValidatable接口織入到原有的Mail類中,這是一種很是形象的introduce功能,其實現仍然是在aspect中完成: import com.acme.validate.Validatable;
public aspect MailValidateAspect { declare parents: Mail implements IValidatable;
public boolean Mail.validateAddress() { if(this.getToAddress() != null) { return true; } else { return false; } } }
靜態橫切的方法,並無引入相似MailAdapter的新類,而是經過定義的MailValidateAspect方面,利用橫切技術爲Mail類introduce了新的方法ValidateAddress(),從而實現了Mail的擴展。所以以下的代碼徹底可行。 Mail mail = new Mail(); IValidatable validate = ((IValidatable)mail).ValidateAddress();
2.3 AOP技術的優點
AOP技術的優點是顯而易見的。在面向對象的世界裏,人們提出了各類方法和設計原則來保障系統的可複用性與可擴展性,以期創建一個鬆散耦合、便於擴展的軟件系統。例如GOF提出的「設計模式」,爲咱們提供了設計的典範與準則。設計模式經過最大程度的利用面向對象的特性,諸如利用繼承、多態,對責任進行分離、對依賴進行倒置,面向抽象,面向接口,最終設計出靈活、可擴展、可重用的類庫、組件,乃至於整個系統的架構。在設計的過程當中,經過各類模式體現對象的行爲、暴露的接口、對象間關係、以及對象分別在不一樣層次中表現出來的形態。然而鑑於對象封裝的特殊性,「設計模式」的觸角始終在接口與抽象中大作文章,而對於對象內部則無能爲力。
經過「橫切」技術,AOP技術就能深刻到對象內部翻雲覆雨,截取方法之間傳遞的消息爲我所用。因爲將核心關注點與橫切關注點徹底隔離,使得咱們可以獨立的對「方面」編程。它容許開發者動態地修改靜態的OO模型,構造出一個可以不斷增加以知足新增需求的系統,就象現實世界中的對象會在其生命週期中不斷改變自身,應用程序也能夠在發展中擁有新的功能。
設計軟件系統時應用AOP技術,其優點在於:
(一)在定義應用程序對某種服務(例如日誌)的全部需求的時候。經過識別關注點,使得該服務可以被更好的定義,更好的被編寫代碼,並得到更多的功能。這種方式還可以處理在代碼涉及到多個功能的時候所出現的問題,例如改變某一個功能可能會影響到其它的功能,在AOP中把這樣的麻煩稱之爲「糾結(tangling)」。
(二)利用AOP技術對離散的方面進行的分析將有助於爲開發團隊指定一位精於該項工做的專家。負責這項工做的最佳人選將能夠有效利用本身的相關技能和經驗。
(三)持久性。標準的面向對象的項目開發中,不一樣的開發人員一般會爲某項服務編寫相同的代碼,例如日誌記錄。隨後他們會在本身的實施中分別對日誌進行處理以知足不一樣單個對象的需求。而經過建立一段單獨的代碼片斷,AOP提供瞭解決這一問題的持久簡單的方案,這一方案強調了將來功能的重用性和易維護性:不須要在整個應用程序中一遍遍從新編寫日誌代碼,AOP使得僅僅編寫日誌方面(logging aspect)成爲可能,而且能夠在這之上爲整個應用程序提供新的功能。
總而言之,AOP技術的優點使得須要編寫的代碼量大大縮減,節省了時間,控制了開發成本。同時也使得開發人員能夠集中關注於系統的核心商業邏輯。此外,它更利於建立鬆散耦合、可複用與可擴展的大型軟件系統。
來源:http://wayfarer.cnblogs.com/articles/241024.html