aop


AOP術語:spring

一、通知(Adivce)this

通知定義了切面是什麼以及什麼時候使用。除了描述切面要完成的工做,通知還解決了什麼時候執行這個工做的問題。它應該應用於某個方法spa

個方法被調用以前?以後?以前和以後?仍是隻在方法拋出異常時?代理

   String 切面能夠應用5種類型的通知orm

a、Before -- 在方法被調用以前調用通知對象

b、After  -- 在方法被調用以後調用通知接口

c、After-returning -- 在方法成功執行以後調用通知生命週期

d、After-throwing -- 在方法拋出異常後調用通知ci

e、Around -- 通知包裹了被通知的方法,在被通知的方法調用以前和調用以後執行自定的行爲get

    二、鏈接點(Joinpoint)

鏈接點是在應用執行過程當中可以插入切面的一個點。

三、切點(Poincut)

四、切面(Aspect)

五、引入(Introduction)

引入容許咱們向現有的類添加新方法或屬性。例如,咱們能夠建立以個Auditable通知類,該類記錄了對象最後一次修改時的

狀態。這很簡單,只需一種方法,setLastModified(Date),和一個實例變量來保存這個狀態。而後,這個新方法和實例變量就

能夠被引入到現有的類中。從而能夠在無需修改這類現有的類的狀況下,讓他們具備新的行爲和狀態。

六、織入(Weaving)

織入是將切面應用到目標對象來建立新的代理對象的過程。切面在指定的鏈接點被織入到目標對象中。在目標對象的生命週期裏

有多個點能夠進行織入。

a、編譯期 -- 切面在目標類編譯時被織入。這種方式須要特殊的編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。

b、類加載器 -- 切面在目標類加載到JVM時被織入。這種方式須要特殊的類加載器(ClassLoader),他能夠在目標類被引入

            應用以前加強該目標類的字節碼。AspectJ5的LTW(loading-time weaving)就支持以這種方式織入切面

c、運行期 -- 切面在應用運行的某個時刻被織入。通常狀況下,在織入切面時,AOP容器會爲目標對象動態的建立一個代理對象。

           Spring AOP 就是以這種方式織入切面的。

Spring 只支持方法鏈接點。 AspectJ和Jboss,除了方法切點,他們還提供了字段和構造器接入點 。Spring缺乏對字段鏈接點的支持,

沒法讓咱們建立細粒度的通知,例如攔截對象字段的修改。並且Spring也不支持構造器鏈接點,咱們也沒法在Bean建立時應用通知。



Spring 的 AOP 配置元素簡化了基於pojo切面的聲明

AOP配置元素                   描述

<aop:advisor>                定義aop通知器

<aop:after>                  定義aop後置通知(無論被通知的方法是否執行成功)

<aop:after-returning>        定義AOP after-returning通知

<aop:after-throwing>         定義after-throwing通知

<aop:around> 定義AOP環繞通知

<aop:aspect>                 定義切面

<aop:aspectj-autoproxy>      啓用@Aspecctj註解驅動的去切面

<aop:before>                 定義AOP前置通知

<aop:config>                 頂層的aop配置,大多數的<aop:*>元素必須包含在<aop:config>元素內

<aop:declare-parents>        爲被通知的對象引入額外的接口,並透明的實現

<aop:pointcut>               定義切點

經過切面引入新功能:

使用Spring AOP,咱們能夠爲Bean引入新的方法。代理攔截調用並委託給實現該方法的其餘對象。咱們須要注意的是,當引入接口的

方法被調用時,代理將此調用委託給實現了新接口的某個其餘獨享。實際上,Bean的實現被拆分到了多個類。

新功能:

package com.springinaction.springidol

public interface Contestant{

void receiveAward();

}

<aop:aspect>

<aop:declare-parents

type-matching = "com.springinaction.springidol.Performer+"

implement-interface="com.springinaction.springidol.Contestant"

default-impl="com.springinaction.springidol.GraciousContestant"

/>

</aop-aspect>

顧名思義,<aop:declare-parents>聲明瞭此切面所通知的Bean在對他的對象層次結構中擁有新的父類型。

具體到本示例中,類型匹配Perpormer接口(由types-match屬性指定)的那些Bean會實現Contestant接口(

由implements-interface屬性指定)。最後要解決的問題是Constestant接口中的方法實現來自於何處

這裏有兩種方式標識所引入接口的實現。在本示例中,咱們使用default-impl屬性經過他的全限定類名來顯示

指定Contestant的實現。或者,咱們還可使用delegate-ref屬性來標識.


<aop:aspect>

<aop:declare-parents

type-matching = "com.springinaction.springidol.Performer+"

implement-interface="com.springinaction.springidol.Contestant"

delegate-ref="contestaantDelegate"

/>

</aop-aspect>

delegate-ref 屬性引用了一個Spring Bean做爲引入的 委託。這須要在Spring上下文中存在一個ID爲contestantDelefate

的Bean。

<bean id="contestaantDelegate" class="com.springinaction.springidol.GraciousContestant"/>

使用def-impl來直接標識委託和間接使用delegate-ref的區別在於後者是Spring Bean,他自己能夠被注入,被通知,或者使用其餘Spring配置

              spring藉助ApectJ的切點表達式語言來定義Spring切面

AspectJ指示器            描述

arg()                   限制鏈接點匹配參數未指定類型的執行方法

@arg()                  限制鏈接點匹配參數由指定註解標註的執行方法

execution()             用於匹配是鏈接點的執行方法

this()                  顯示鏈接點匹配AOP代理的Bean應用爲指定類型的類

target()                限制鏈接點匹配目標對位爲指定類型的類

@target()               限制鏈接點匹配特定的執行對象,這些對象對應的類要具有指定類型的註解

                within()                限制鏈接點匹配指定的類型

                @with()                 限制鏈接點匹配指定註解所標註的類型(當使用AOP時,方法定義在由指定的註解所標註的類裏)

           @annotation             限制匹配帶有指定註解鏈接點

相關文章
相關標籤/搜索