1. 程式人生 > >SpringMVC學習筆記(三) 切面詳解

SpringMVC學習筆記(三) 切面詳解

為了更好的理解AOP,先來了解幾個AOP的術語。

通知(Advice)

指切面(定義為aspect的類)中的工作;

spring切面可以應用的五種通知

前置通知(Before):在目標方法被呼叫之前呼叫通知功能;

後置通知(After):在目標方法完成之後呼叫通知,此時不會關心方法的輸出是什麼;

返回通知(After-returning):在目標方法成功執行之後呼叫通知;

異常通知(After-throwing):在目標方法丟擲異常後呼叫通知;

環繞通知(Around):通知報過了被通知的方法,在被通知的方法呼叫之前和呼叫之後執行自定義的行為。

連線點(Join point)

連線點是在應用執行過程中能夠插入切面的一個點。這個點可以是呼叫方法時,丟擲異常時,甚至修改一個欄位時。切面程式碼可以利用這些點插入到應用的正常流程之中,並新增新的行為。(切點方法中配置的匹配的方法都是連線點)

切點(Pointcut)

定義通知所要織入的一個或多個連線點。

切面(Aspect)

是通知和切點的結合。

引入(Introduction)

向現有的類新增新的方法和屬性。

織入(Weaving)

織入是把切面應用到目標物件並建立新的代理物件的過程。切面在指定的連線點被織入到目標物件中。在目標物件的生命週期裡有多個點可以進行織入:

編譯期:切面在目標類編譯時被織入,這種方式需要特殊的編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。

類載入期:切面在目標類載入到jvm時被織入。這種方式 需要特殊的類載入器(ClassLoader),它可以在目標類被引入應用之前增強該目標類的位元組碼。AspectJ5的載入時織入(load-time weaving,LTW)就支援以這種方式織入切面。

執行期:切面在應用執行的某個時刻被織入。一般情況下,在織入切面時,AOP容器會為目標物件動態的建立一個代理物件。Spring AOP就是以這種方式織入切面的。

下圖展示了這些概念是如何聯絡在一起的。


下面瞭解一下具體的切點表示式。在spring的切面中,主要使用execution指示器來設定匹配的方法。下圖中的表示式能夠設定當sleep()方法執行時觸發的通知呼叫。
execution()指示器選擇ViewControllersleep()方法,方法表示式以“*”號開始,表明了不關心方法返回值的型別。然後,指定了全限定方法名和類名。對於方法引數列表,使用兩個點號(. .)表明切點要選擇任意的sleep

()方法,不需要考慮入參。


使用AspectJ切點表示式來選擇ViewController的sleep方法
如果我們需要設定切點僅適用於某個包下的方法,則可以使用within()指示器來指定,不同的指示器之間使用&&(and)或||(or)連線。如下圖表達式,表示只匹配com.spring包下的ViewControllersleep()方法。
spring中還引入了bean()指示器,可以限制切點只匹配特定的bean,也可以使用!bean()來匹配除了特定bean以外的其他bean。如下: execution(*  com.spring.ViewController.sleep())   and  bean ("rest") execution(*  com.spring.ViewController.sleep())   and  !bean ("rest")
下面寫一個切面的demo。 首先,在com.spring下的ViewController類中新增一個sleep()方法如下:
 @RequestMapping("/sleep")
    public String sleep(){
        System.out.println("sleeping………………zzzZZZ~~~~");
        return "index";
    }


然後,新增切面程式碼。使用註解新建一個切面SleepHelper,程式碼如下。
@Component
@Aspect
public class SleepHelper {

    public SleepHelper(){
        
    }
    
    @Pointcut("execution(* com.spring.controller.ViewController.*(..))")
    public void sleeppoint(){
    }
    
    @Before("sleeppoint()")
    public void beforeSleep(){

        System.out.println("馬上要睡覺咯~~~");
    }
    
    @AfterReturning("sleeppoint()")
    public void afterSleep(){

        System.out.println("睡醒咯!");
    }
    
}

最後,專案是maven的專案,所以需要在pom.xml中新增切面對應的依賴jar包,並在applicationContext.xml檔案中新增下圖紅框中的內容: 第一個紅框中內容作用:宣告spring的aop的名稱空間; 第二個紅框中內容作用:啟用aspectj的自動代理;

完成上述配置後,啟動專案,瀏覽器中輸入http://localhost:8080/sleep,控制檯就會有如下輸出:


OK,至此,一個簡單的切面應用就完成咯~~~