Spring源碼-AOP(二)-AOP概念

轉(zhuǎn)自:青離的博客.請去原創(chuàng)作者博客看

1.AOP概念

AOP中文翻譯為面向方面編程或面向切面編程,維基百科對它的解釋是

AOP指一種程序設(shè)計范型,該范型以一種稱為aspect(切面)的語言構(gòu)造為基礎(chǔ),切面是一種新的模塊化機制,用來描述分散在對象、類或函數(shù)中的橫切關(guān)注點(crosscutting concern)。

談到模塊化機制,自然會想到OOP(面向?qū)ο缶幊?。OOP也是一種模塊化的方法,它將數(shù)據(jù)和處理方法組合在一起,擺脫了函數(shù)式中數(shù)據(jù)雜亂無章的場景,使得程序的功能整齊且清晰,并且通過設(shè)計類的繼承關(guān)系讓代碼得以重用,進一步提高開發(fā)效率。之后出現(xiàn)的多種設(shè)計模式使得程序設(shè)計更加便捷方便。

然而世界是復(fù)雜的,盡管OOP已經(jīng)能夠解決大部分的問題,還是存在一些非強業(yè)務(wù)相關(guān)的通用功能,明明大家都需要,一旦要歸類卻發(fā)現(xiàn)很復(fù)雜,往往最后寫出來一個工具類。這些功能就如同城市中的水電交通一般,滲透到家家戶戶中,卻不能交由每家每戶自己來維護。這些功能就像城市的一個個切面,需要一個統(tǒng)籌管理的方式。這個就是AOP形成的原因。

而什么叫橫切關(guān)注點?先解釋下關(guān)注點,就是對軟件工程有意義的小的,可管理的可描述的軟件組成部分。太拗口了對不對,我的理解就是一個操作一個方法都是對一個關(guān)注點的實現(xiàn),比如插入訂單,扣減庫存,記錄日志等等。而有些關(guān)注點是軟件的核心功能,稱為主關(guān)注點,比如插入訂單,有些關(guān)注點則彌散在軟件內(nèi)部,比如記錄日志,這些關(guān)注點同許多不同的主關(guān)注點都有交集,稱為橫切關(guān)注點。主關(guān)注點大都通過OOP的方式去設(shè)計更加清晰,而從主關(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)用程序中的變動就可以很好的管理起來。

維基百科中對面向切面編程的操作方式給了很專業(yè)的解說。而當前已經(jīng)出現(xiàn)了AOP的特定實現(xiàn)或AOP相關(guān)技術(shù),比如

  • AspectJ:源代碼和字節(jié)碼級別的編織器,需用使用Aspect語言
  • AspectWerkz:AOP框架,使用字節(jié)碼動態(tài)編織器和XML配置
  • JBoss-AOP:基于攔截器和元數(shù)據(jù)的AOP框架,運行在JBoss應(yīng)用服務(wù)器上
  • BCEL(Byte-Code Engineering Library):Java字節(jié)碼操作類庫
  • Javassist:Java字節(jié)碼操作類庫

同時有一個AOP聯(lián)盟對AOP做了一個抽象和規(guī)范,形成了一個三層的代表性架構(gòu),以及一個通用的AOP API,這個API就是經(jīng)常使用的aopalliance-api-1.0.jar。它定義了AOP的幾個通用接口:

  • 連接點(Join Point):程序執(zhí)行過程中的某個點,如方法的調(diào)用或異常的處理
  • 增強(Advice):對特定連接點的動作的擴展或改變
  • 攔截器(Inteceptor):繼承了Advice接口,增強(Advice)模型的封裝,一般圍繞連接點形成攔截器鏈
  • 調(diào)用(Invocation):繼承了JoinPoint接口,指圍繞連接點的攔截器觸發(fā)的調(diào)用

而對于增強(Advice),通常又分為以下幾種類型

  • 前置增強(Before advice):在連接點之前執(zhí)行,它不能阻止流程繼續(xù)執(zhí)行(除非拋出異常)
  • 后置增強(After returning advice):連接點正常完成后將被執(zhí)行
  • 最終增強(After finally advice):無論連接點是否正常執(zhí)行完成,最后都將被執(zhí)行(相當于finally語句)
  • 拋出增強(After throwing advice):當方法拋出一個異常時將被執(zhí)行
  • 環(huán)繞增強(Around advice):最強大的增強方式,圍繞連接點的增強。它可以在方法執(zhí)行前后觸發(fā)自定義行為,甚至可以選擇是否執(zhí)行原方法以及通過定義自己的返回值或拋出異常來提前結(jié)束方法執(zhí)行。

2.Spring AOP

在AOP框架的實現(xiàn)上,在Spring之前已經(jīng)已有很多,但Spring做出了一些獨特的創(chuàng)新。

1 . 完全由java實現(xiàn),無須特殊的編譯過程。無論是AspectJ還是JBoss-AOP,都需要特定的編譯器。對于追求便捷的開發(fā)者來說,無疑并不是最優(yōu)的。

2 . 集成IOC容器,從而解決企業(yè)應(yīng)用上的通用問題。這點上,Spring并不是最完善的AOP框架,但是其自身的AOP實現(xiàn)以及同AspectJ的集成,已經(jīng)能覆蓋從簡單到復(fù)雜的絕大部分使用場景,而注解的使用更是大大簡化了AOP的配置。

而Spring AOP在實現(xiàn)過程中,對Aop聯(lián)盟定義的API進行了擴展和增強。

  • 增強(Advice):沿用AOP聯(lián)盟的接口
  • 切點(Pointcut):相當于連接點(Join Point),增加了getClassFilter和getMethodMatcher兩個接口方法,用于對不同Advice的所作用的橫切關(guān)注點的過濾和匹配。
  • 切面(Advisor):結(jié)合增強與切點,形成切面。

而對于AOP的具體實現(xiàn),Spring AOP默認使用JDK的動態(tài)代理來代理接口。而對于沒有實現(xiàn)接口的類,或非接口中的方法,則通過CGLIB來實現(xiàn)代理。通過Advisor封裝Advice和Pointcut并初始化成攔截器鏈,當方法調(diào)用請求時,匹配其所圍繞的所有Advisor,然后按順序執(zhí)行,從而達到面向切面編程的核心,分離出橫切關(guān)注點進行統(tǒng)一配置與管理。具體的實現(xiàn)方式將在之后的章節(jié)里詳細介紹。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容