上篇我們學習了AOP的基本概念,我們回顧一下上篇提到的Advice(通知):所謂通知是指攔截到joinpoint(連接點)之後所要做的事情就是通知.通知分爲前置通知,後置通知,異常通知,環繞通知。
Spring.NET的通知既可由某個類的所有對象共享,也可由該類型的單個實例獨佔。共享的通知稱爲基於類型(per-class)的通知,而獨佔的通知稱爲基於實例(per-instance)的通知。
基於類型的通知最爲常用。很多常用功能很適合用基於類型的通知實現,比如說事務。它們不依賴於目標對象的狀態,也不會向目標對象添加新狀態,僅僅對方法及其參數進行操作。
基於實例的通知比較適合做引入(introductions)。此時通知可以向目標對象添加狀態。在AOP代理中,可以同時使用基於類型和基於實例的通知。Spring.NET和spring框架略有不同,只有四種通知類型,沒有spring框架的最終通知(目前我還沒有實現最終通知,如果有朋友實現的話,可以給我留言)。
一、攔截環繞通知(around advice):Spring.NET中最基本的通知類型是攔截環繞通知(interception around advice),即方法攔截器。攔截環繞通知繼承IMethodInterceptor接口。注意其中IMethodInvocation.Proceed()方法的調用。該方法會依次調用攔截器鏈上的其它攔截器。大部分攔截器都需要調用這個方法並返回它的返回值。當然,也可以不調用Proceed方法,而返回一個其它值或拋出一個異常,但一般不太會這麼做。
二、前置通知(before advise):是在IMethodInterceptor.Proceed()方法調用前的通知。繼承自IMethodBeforeAdvice接口。
三、異常通知(throws advise):是在IMethodInterceptor.Proceed()方法調用時發生異常的通知。繼承自IthrowsAdvice接口。IthrowsAdvice接口沒有定義任何方法:它是一個標識接口(按:之所以用標識接口,原因有二:1、在通知方法中,只有最後一個參數是必須的。如果聲明爲接口的方法,參數列表就被固定了。2、如果第一個原因可以用重載的接口方法解決,那麼這個原因就是使用標識接口的充分原因了:實現此接口的類必須聲明一或多個通知方法,接口方法做不到這一點),用以表明實現它的類聲明瞭一或多個強類型的異常通知方法。
四、後置通知(after returning advise):是在IMethodInterceptor.Proceed()方法調用後的通知。繼承自IAfterReturningAdvice接口。後置通知對切入點的執行沒有影響,如果通知拋出異常,就會沿攔截器鏈向上拋出,從而中斷攔截器鏈的繼續執行。
代碼實現:
準備條件
四種通知:
接口:
一、沒有異常的情況
輸出效果:見圖1
圖1
二、有異常的情況:
輸出效果:見圖2
圖2
從圖與代碼中,我們不難看出Advice(通知)的生命週期。攔截環繞通知(around advice)圍繞着整個攔截過程;前置通知(before advise)在方法調用前執行;異常通知(throws advise)在調用方法時發生異常才執行,否則不執行;後置通知(after returning advise)在方法調用後執行,當調用時出現異常,則不執行後置通知(after returning advise)。