Spring AOP---基礎簡介

       軟件開發中,分佈於應用中多處的功能被稱爲橫切關注點,比如日誌、安全和事務管理。這些橫切關注點從概念上是與應用的業務邏輯相分離的,但是往往又直接嵌入到應用的業務邏輯中。將這些橫切關注點與業務邏輯相分離正是面向切面編程(AOP)所要解決的。
       依賴注入有助於應用對象之間的解耦,而AOP可以實現橫切關注點與它們所影響的對象之間的解耦。

       橫切關注點可以被模塊化爲特殊的類,這些類被稱爲切面。這樣做有兩個好處:首先,每個關注點現在都只集中於一處,而不是分散到多處代碼中;其次,服務模塊更簡潔,因爲它們只包含主要關注點(或核心功能)的代碼,而次要關注點的代碼被轉移到切面中了。

       1.AOP術語:


       >.通知(Advice):在AOP中,切面的工作被稱爲通知
       通知定義了切面是什麼以及何時使用。除了描述切面要完成的工作,通知還解決了何時執行這個工作的問題。
Spring切面可以應用5種類型的通知:
       (1)Before---在方法被調用之前調用通知;
       (2)After---在方法完成之後調用通知,無論方法執行是否成功;
       (3)After-returning---在方法成功執行之後調用通知;
       (4)After-throwing---在方法拋出異常後調用通知;
       (5)Around---通知包裹了被通知的方法,在被通知的方法調用之前和調用之後執行自定義的行爲。

       >.連接點(Joinpoint):連接點是在應用執行過程中能夠插入切面的一個點
這個點可以是調用方法時、拋出異常時、甚至修改一個字段時。切面代碼可以利用這些點插入到應用的正常流程中,並添加新的行爲。

       >.切點(Poincut):一個切面並不需要通知應用的所有連接點。切點有助於縮小切面所通知連接點的範圍。
切點的定義會匹配通知所要織入的一個或多個連接點。通常使用明確的類和方法名來指定這些切點,或是利用正則表達式定義匹配的類和方法名稱模式來指定這些切點。

       >.切面(Aspect):切面是通知和切點的結合。通知和切點共同定義了關於切面的全部內容---它是什麼,在何時和何處完成其功能。

       >.引入(Introduction):引入允許我們向現有的類添加新方法或屬性。

       >.織入(Weaving):織入是將切面應用到目標對象來創建新的代理對象的過程。切面在指定的連接點被織入到目標對象中。在目標對象的生命週期裏有多個點可以進行織入:
       (1)編譯期---切面在目標類編譯時被織入。需要特殊編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。
       (2)類加載期---切面在目標類加載到JVM時被織入。這種方式需要特殊的類加載器(ClassLoader),它可以在目標類被引入應用之前增強目標類的字節碼。
       (3)運行期---切面在應用運行的某個時刻被織入。一般情況下,在織入切面時,AOP容器會爲目標對象動態創建一個代理對象。Spring AOP就是以這種方式織入切面的。

       2.Spring對AOP的支持


       創建切點來定義切面織入的連接點是AOP框架的基本功能。
       目前的AOP框架主要有:
        >.AspectJ(
http://eclipse.org/aspectj);
        >.JBoss AOP(
http://www.jboss.org/jbossaop);
        >.Spring AOP(
http://www.springframework.org)。
        Spring提供了4中各具特色的AOP支持:
        >.基於代理的經典AOP;
        >.@AspectJ註解驅動的切面;
        >.純POJO切面;
        >.注入式AspectJ切面(適合Spring各版本)。

        Spring通知是Java編寫的。Spring在運行期通知對象:
        通過在代理類中包裹切面,Spring在運行期將切面織入到Spring管理的Bean中。

         

      如上圖所示,代理類封裝了目標類,並攔截被通知的方法的調用,再將調用轉發給真正的目標Bean。
       當攔截到方法調用時,在調用目標Bean方法之前,代理會執行切面邏輯。直到應用需要被代理的Bean時,Spring才創建代理對象。如果使用的是ApplicationContext,在ApplicationContext從BeanFactory中加載所有Bean時,Spring創建被代理的對象。因爲Spring運行時才創建代理對象,所以不需要特殊的編譯器來織入Spring AOP的切面。由於Spring基於動態代理,因此Spring只支持方法連接點。如果需要方法攔截之外的連接點攔截,可以利用AspectJ來協助Spring AOP。

       3.使用切點選擇連接點


       在Spring AOP中,使用AspectJ的切點表達式語言來定義切點。Spring僅支持AspectJ切點指示器的一個子集。

         

       在Spring中嘗試使用AspectJ其他指示器時,會拋出IllegalArgumentException異常。另外,上述指示器中,只有execution指示器是唯一的執行匹配,其他的都是用於限制匹配的。這說明,execution指示器是我們編寫切點定義時最主要使用的指示器。在此基礎上,使用其他指示器來限制所匹配的切點。

          

           

           

          上面我們使用"&&"把execution和within指示器連在一起形成與關係,同樣,可以使用"||"來表示或關係,使用"!"表示非關係。

        除了上面的指示器意外,Spring2.5引入了新的bean()指示器,使用該指示器,我們可以在切點表達式中使用Bean的ID來標識Bean。

         eg.

         execution(*  com.springaction.aop.domain.Perfomer.perform(..)) and bean(duke)

         上面的例子中,在執行 Perfomer 的 perform方法時應用通知,但限定Bean的ID爲duke。

       4.在XML中聲明切面

       

         5.註解切面

         使用註解創建切面是AspectJ 5引入的關鍵特性。使用AspectJ面向註解的模型可以非常簡便的通過少量註解將人以類轉變爲切面。

       6.注入AspectJ切面

       雖然Spring AOP能滿足許多應用的切面需求,但與AspectJ相比,Spring AOP扔是一個功能比較弱的AOP解決方案。AspectJ提供了Spring AOP所不能支持的許多類型的切點。

       下節會給出具體的配置demo。

       以上內容主要來自《Spring in action》的讀書筆記。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章