AOP
一,AOP概念
AOP是Aspect-OrientedProgramming(面向方面編程或面向切面)的簡稱,維基百科對它的解釋如下。
維基百科對“AOP” 相關(guān)概念的敘述 Aspect是一-種新的模塊化機制,用來描述分散在對象、類或函數(shù)中的橫切關(guān)注點(crosscutting concern)。
從關(guān)注點中分離出橫切關(guān)注點是面向切面的程序設(shè)計的核心概念。分離關(guān)注點使解決特定領(lǐng)域問題的代碼從業(yè)務(wù)邏輯中獨立出來,
業(yè)務(wù)邏輯的代碼中不再含有針對特定領(lǐng)域問題代碼的調(diào)用,業(yè)務(wù)邏輯同特定領(lǐng)域問題的關(guān)系通過切面來封裝、維護,這樣原本分散在整個應(yīng)用程序中的變動就可以很好地管理起來。
這里提到的概念是從模塊化出發(fā)的,開發(fā)者一定不會對模塊化這個概念感到陌生。記得我初學(xué)編程(C語言)時,總喜歡把所有代碼寫進一個main函數(shù)里。這種編碼方式造成了一個很不好的后果一程序的維護性很差。如果程序規(guī)模較小,而且是由一個人開發(fā)完成的,維護時還能控制;如果程序規(guī)模較大,而且需要多個人合作才能完成,維護時就會遇到很大的麻煩。再加上當(dāng)時根本沒有版本管理的概念,隨著項目進展,功能越加越多,整個程序就逐漸變成了一團亂麻。
經(jīng)過一段痛苦的經(jīng)歷后,我終于在開發(fā)實踐中對軟件工程的相關(guān)概念有了一些認識,開始明白了自己原來只是在寫程序,并不是在開發(fā)軟件,更談不上是在開發(fā)軟件產(chǎn)品了。痛定思痛,我不斷地在編碼中學(xué)習(xí)和思考,開始使用子函數(shù)來對程序進行模塊劃分,并對些基本的功能進行封裝。當(dāng)時只是希望一個函數(shù)不要太長,能把不同的功能模塊分給不同的開發(fā)人員完成。想法雖簡單,但每個開發(fā)人員都渴望這樣做,就像普通開發(fā)人員對優(yōu)秀的架構(gòu)師的褐望一樣。有了架構(gòu)師,每個人就可以各自負責(zé)自己的“一畝三分地”,日子也許就好過了!
但是很不幸,萬能的架構(gòu)師始終沒有出現(xiàn),最后只能自己想辦法:在工作中總結(jié),在教訓(xùn)中學(xué)習(xí),在摸索中前進。在成長的過程中,很自然地發(fā)現(xiàn),將些代碼用子函數(shù)封裝以后,只要把接口定義設(shè)計好,子函數(shù)中的代碼變動是不會對主程序中的代碼產(chǎn)生太大影響的,從而大大降低了維護的成本。
后來,為了讓代碼的維護更方便,又把不同的子函數(shù)的實現(xiàn)放到了不同的文件中。這樣更方便了,不僅不用在一長串的代碼文件里查找和維護,還可以讓不同的開發(fā)人員并行開發(fā)和維護,大大提高了開發(fā)效率。除了技術(shù)方面的提高,還有精神上的收獲。這種分而治之的策略讓我慢慢具備了設(shè)計大型程序的信心,不會再為那些長長的代碼感到頭疼。用這種方法來編寫一般的C語言程序基本沒問題,直到后來涉及面向?qū)ο蟮某绦蛟O(shè)計,新的問 題又出現(xiàn)了。
有了一定的面向?qū)ο缶幊探?jīng)驗后發(fā)現(xiàn),面向?qū)ο笤O(shè)計其實也是種模塊化的方法,它把相關(guān)的數(shù)據(jù)及其處理方法放在了一起。與單純使用子函數(shù)進行封裝相比,面向?qū)ο蟮哪K化特性更完備,它體現(xiàn)了計算的一個基本原則------讓計算盡可能靠近數(shù)據(jù)。這樣一來,代碼組織起來就更加整齊和清晰,一個類就是一個基本的模塊。很多程序的功能還可以通過設(shè)計類的繼承關(guān)系而得到重用,進一步提高了開發(fā)效率。再后來,又出現(xiàn)了各種各樣的設(shè)計模式,使設(shè)計程序功能變得更加得心應(yīng)手。
后來又在開發(fā)中發(fā)現(xiàn)了一些問題。雖然利用面向?qū)ο蟮姆椒梢院芎玫亟M織代碼,也可以通過繼承關(guān)系實現(xiàn)代碼重用,但是程序中總是會出現(xiàn)一些重復(fù)的代碼,而且不太方便使用繼承的方法把它們重用和管理起來。它們功能重復(fù)并且需要用在不同的地方,雖然可以對這些代碼做一些簡單的封裝,使之成為公共函數(shù),但是在這種顯式的調(diào)用中,使用它們并不是很方便。例如,這個公共函數(shù)在什么情況下可以使用,能不能更靈活地使用等。
另外,在使用這些公共函數(shù)的時候,往往也需要進行一些邏輯設(shè)計,也就是需要代碼實現(xiàn)來支持,而這些邏輯代碼也是需要維護的。這時就是AOP大顯身手的時候,使用AOP后,不僅可以將這些重復(fù)的代碼抽取出來單獨維護,在需要使用時統(tǒng)一調(diào)用,還可以為如何使用這些公共代碼提供豐富靈活的手段。這雖然與設(shè)計公共子模塊有幾分相似,但在傳統(tǒng)的公共子模塊調(diào)用中,除了直接硬調(diào)用之外并沒有其他的手段,而AOP為處理這一類問題提供了一套完整的理論和靈活多樣的實現(xiàn)方法。也就是說,通過AOP提出橫切的概念以后,在把模塊功能正交化的同時,也在此基礎(chǔ)上提供了一系列橫切的靈活實現(xiàn)。比如通過使用Proxy代理對象、攔截器字節(jié)碼翻譯技術(shù)等一系列已有的AOP或者AOP實現(xiàn)技術(shù),來實現(xiàn)切面應(yīng)用的各種編織實現(xiàn)和環(huán)繞增強;為了更好地應(yīng)用AOP技術(shù),技術(shù)專家們還成立了AOP聯(lián)盟來探討 AOP的標(biāo)準(zhǔn)化,有了這些支持,AOP的發(fā)展就更快了。關(guān)于AOP技術(shù),可以到AOP聯(lián)盟的文檔里找到一些相關(guān)的介紹,從而加強對AOP的理解。比如,在AOP聯(lián)盟的網(wǎng)站上有以下AOP技術(shù)
O AspectJ:源代碼和字節(jié)碼級別的編織器,用戶需要使用不同于Java的新語言。O AspectWerkz: AOP框架,使用字節(jié)碼動態(tài)編織器和XML配置。
O JBoss-AOP:基于攔截器和元數(shù)據(jù)的AOP框架,運行在JBoss應(yīng)用服務(wù)器上,以及在AOP中用到的一些相關(guān)的技術(shù)實現(xiàn)
O BCEL (Byte-Code Engineering Library): Java字 節(jié)碼操作類庫,具體的信息可以參見項目網(wǎng)站http://jakarta.apache.org/bcel/.
O Javassist: Java字節(jié)碼操作類庫,JBoss的一個子項目,項目信息可以參見項目網(wǎng)站http://jboss .org/javassist/
對應(yīng)于現(xiàn)有的AOP實現(xiàn)方案,AOP聯(lián)盟對它們進行了一定程度的抽象,從而定義出AOP體系結(jié)構(gòu)。結(jié)合這個AOP體系結(jié)構(gòu)去了解AOP技術(shù),對我們理解AOP的概念是非常有幫助的,AOP聯(lián)盟定義的AOP體系結(jié)構(gòu)如圖3-1所示
AOP聯(lián)盟定義的AOP體系結(jié)構(gòu)把與AOP相關(guān)的概念大致分為由高到低、從使用到實現(xiàn)的三個層次。從上往下,最高層是語言和開發(fā)環(huán)境,在這個環(huán)境中可以看到幾個重要的概念:“基礎(chǔ)”(base)可以視為待增強對象或者說目標(biāo)對象;“切面”(aspect)通常包含對于基礎(chǔ)的增強應(yīng)用;“配置”(configuration)可以看成是一種編織,通過在AOP體系中提供這個配置環(huán)境,可以把基礎(chǔ)和切面結(jié)合起來,從而完成切面對目標(biāo)對象的編織實現(xiàn)。
在SpringAOP實現(xiàn)中,使用Java語言來實現(xiàn)增強對象與切面增強應(yīng)用,并為這兩者的結(jié)合提供了配置環(huán)境。對于編織配置,毫無疑問,可以使用IoC容器來完成;對于POJO對象的配置,本來就是Spring的核心IoC容器的強項。因此,對于使用Spring的AOP開發(fā)而言,使用POJO就能完成AOP任務(wù)。但是,對于其他的AOP實現(xiàn)方案,可能需要使用特定的實現(xiàn)語言、配置環(huán)境甚至是特定的編譯環(huán)境。例如在AspectJ中,盡管切面增強的對象是Java對象,但卻需要使用特定的Aspect語言和AspectJ編譯器。AOP體系結(jié)構(gòu)的第二個層次是為語言和開發(fā)環(huán)境提供支持的,在這個層次中可以看到AOP框架的高層實現(xiàn),主要包括配置和編織實現(xiàn)兩部分內(nèi)容。例如配置邏輯和編織邏輯實現(xiàn)本身,以及對這些實現(xiàn)進行抽象的一些高層API封裝。這些實現(xiàn)和API封裝,為前面提到的語言和開發(fā)環(huán)境的實現(xiàn)提供了有力的支持。
最底層是編織的具體實現(xiàn)模塊,圖3-1中的各種技術(shù)都可以作為編織邏輯的具體實現(xiàn)方法,比如反射、程序預(yù)處理、攔截器框架、類裝載器框架、元數(shù)據(jù)處理等。閱讀完本章對SpringAOP實現(xiàn)原理的分析,我們可以了解到,在SpringAOP中,使用的是Java本身的語言特性,如JavaProxy代理類、攔截器等技術(shù),來完成AOP編織的實現(xiàn)。
對Spring平臺或者說生態(tài)系統(tǒng)來說,AOP是Spring框架的核心功能模塊之。AOP與IoC容器的結(jié)合使用,為應(yīng)用開發(fā)或Spring自身功能的擴展都提供了許多便利。SpringAOP的實現(xiàn)和其他特性的實現(xiàn)樣,除了可以使用Spring本身提供的AOP實現(xiàn)之外,還封裝了業(yè)界優(yōu)秀的AOP解決方案AspectJ來供應(yīng)用使用。本章主要對Spring自身的AOP實現(xiàn)原理進行分析。在這個AOP實現(xiàn)中,Spring充分利用了IoC容器Proxy代理對象以及AOP攔截器的功能特性,通過這些對AOP基本功能的封裝機制,為用戶提供了AOP的實現(xiàn)框架。因此,要了解這些AOP的基本實現(xiàn),需要對Java的Proxy機制有一些基本了解。在Spring中,有-些相關(guān)的概念與AOP設(shè)計相對應(yīng)。本章將按照筆者個人的理解,結(jié)合Spring的AOP實現(xiàn),先簡單地回顧一些相關(guān)的AOP概念,然后逐步展開對AOP實現(xiàn)原理的分析,通過對實現(xiàn)原理的分析來了解SpringAOP模塊,在這些實現(xiàn)原理的分析中,包括代理對象的生成、AOP攔截器的實現(xiàn)等。在分析中,以ProxyFactoryBean和ProxyFactory為例進行說明。
總結(jié)
- 上一篇: ActiveMQ基础教程(二):安装与配
- 下一篇: SWT中各种参数大全