Spring aop學習整理(spring in action)(一):了解AOP
切面能幫助我們模塊化橫切關註點。簡而言之,橫切關註點可以被描述為影響應用多處的功能。例如,安全就是一個橫切關註點,應用中的許多方法都會涉及到安全規則。圖4.1直觀呈現了橫切關註點的概念。
圖4.1展現了一個被劃分為模塊的典型應用。每個模塊的核心功能都是為特定業務領域提供服務,但是這些模塊都需要類似的輔助功能,例如安全和事務管理。如果要重用通用功能的話,最常見的面向對象技術是繼承(inheritance)或委托(delegation)。但是,如果在整個應用中都使用相同的基類,繼承往往會導致一個脆弱的對象體系;而使用委托可能需要對委托對象進行復雜的調用。切面提供了取代繼承和委托的另一種可選方案,而且在很多場景下更清晰簡潔。在使用面向切面編程時,我們仍然在一個地方定義通用功能,但是可以通過聲明的方式定義這個功能要以何種方式在何處應用,而無需修改受影響的類。橫切關註點可以被模塊化為特殊的類,這些類被稱為切面(aspect)。這樣做有兩個好處:首先,現在每個關註點都集中於一個地方,而不是分散到多處代碼中;其次,服務模塊更簡潔,因為它們只包含主要關註點(或核心功能)的代碼,而次要關註點的代碼被轉移到切面中了。
AOP術語:
與大多數技術一樣,AOP已經形成了自己的術語。描述切面的常用術語有通知(advice)、切點(pointcut)和連接點(join point)。圖4.2展示了這些概念是如何關聯在一起的。
遺憾的是,大多數用於描述AOP功能的術語並不直觀,盡管如此,它們現在已經是AOP行話的組成部分了,為了理解AOP,我們必須了解這些術語。在我們進入某個領域之前,必須學會在這個領域該如何說話。
通知(Advice):
在AOP術語中,切面的工作被稱為通知。
通知定義了切面是什麽以及何時使用。除了描述切面要完成的工作,通知還解決了何時執行這個工作的問題。它應該應用在某個方法被調用之前?之後?之前和之後都調用?還是只在方法拋出異常時調用?
Spring切面可以應用5種類型的通知:
1.前置通知(Before):在目標方法被調用之前調用通知功能
2.後置通知(After):在目標方法完成之後調用通知,此時不會關心方法的輸出是什麽
3.返回通知(After-returning):在目標方法成功執行之後調用通知
4.異常通知(After-throwing):在目標方法拋出異常後調用通知
5.環繞通知(Around):通知包裹了被通知的方法,在被通知的方法調用之前和調用之後執行自定義的行為
連接點(Join point):
我們的應用可能也有數以千計的時機應用通知。這些時機被稱為連接點。連接點是在應用執行過程中能夠插入切面的一個點。這個點可以是調用方法時、拋出異常時、甚至修改一個字段時。切面代碼可以利用這些點插入到應用的正常流程之中,並添加新的行為
切點(Poincut):
如果說通知定義了切面的“什麽”和“何時”的話,那麽切點就定義了“何處”。切點的定義會匹配通知所要織入的一個或多個連接點。我們通常使用明確的類和方法名稱,或是利用正則表達式定義所匹配的類和方法名稱來指定這些切點。有些AOP框架允許我們創建動態的切點,可以根據運行時的決策(比如方法的參數值)來決定是否應用通知。
切面(Aspect):
切面是通知和切點的結合。通知和切點共同定義了切面的全部內容——它是什麽,在何時和何處完成其功能。
引入(Introduction):
引入允許我們向現有的類添加新方法或屬性。例如,我們可以創建一個Auditable通知類,該類記錄了對象最後一次修改時的狀態。這很簡單,只需一個方法,setLastModified(Date),和一個實例變量來保存這個狀態。然後,這個新方法和實例變量就可以被引入到現有的類中,從而可以在無需修改這些現有的類的情況下,讓它們具有新的行為和狀態。
織入(Weaving):
織入是把切面應用到目標對象並創建新的代理對象的過程。切面在指定的連接點被織入到目標對象中。在目標對象的生命周期裏有多個點
可以進行織入:
1.編譯期:切面在目標類編譯時被織入。這種方式需要特殊的編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。
2.類加載期:切面在目標類加載到JVM時被織入。這種方式需要特殊的類加載器(ClassLoader),它可以在目標類被引入應用之前增強該目標類的字節碼。AspectJ 5的加載時織入(load-timeweaving,LTW)就支持以這種方式織入切面。
3.運行期:切面在應用運行的某個時刻被織入。一般情況下,在織入切面時,AOP容器會為目標對象動態地創建一個代理對象。Spring AOP就是以這種方式織入切面的。
Spring aop學習整理(spring in action)(一):了解AOP