您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Spring.net中怎么實現Aop編程,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
一. 什么是AOP
AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程(也叫面向方面),可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加 功能的一種技術。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。
主要的功能是:日志記錄,性能統計,安全控制,事務處理,異常處理等等。
主要的意圖是:將日志記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯代碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非指導業務邏輯的方法中,進而改變這些行為的時候不影響業務邏輯的代碼。
可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。
在Spring中提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例 如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們并 不負責(甚至是意識)其它的系統級關注點,例如日志或事務支持。
切面(Aspect)
切面是你要實現的交叉功能。它是應用系統模塊化的一個切面或領域。切面的最常見(雖然簡單)例子是日志記錄。日志記錄在系統中到處需要用到,利用繼承來重用日志模塊不適合。然而,你可以創建一個日志記錄切面,并且使用AOP在系統中應用。
連接點(Joinpoint)
連接點是應用程序執行過程中插入切面的地點。這個地點可以是方法調用,異常拋出,或者甚至是要修改的字段。切面代碼在這些地方插入到你的應用流程中,添加新的行為。
通知(Advice)
通知切面的實際實現。它通知應用系統新的行為。在日志例子中,日志通知包含了實現實際日志功能的代碼,如向日志文件寫日志。通知在連接點插入到應用系統中。
切入點(Pointcut)
切入點定義了通知應該應用在哪些連接點。通知可以應用到AOP框架支持的任何連接點。當然,你并不希望把所有切面應用到所有可能的連接點上。切入點讓你指定通知應用到什么地方。通常通過指定類名和方法名,或者匹配類名和方法名式樣的正則表達式來指定切入點。一些AOP框架允許動態創建切入點,在運行時根據條件決定是否應用切面,如方法參數值。
引入(Introduction)
引入允許你為已存在類添加新方法和屬性。例如,你可以創建一個稽查通知來記錄對象的***修改時間。只要用一個方法setLastMofified(Date)以及一個保存這個狀態的變量。可以在不改變已存在類的情況下將這個引入,給他們新的行為和狀態。
目標對象(Target)
目標對象是被通知對象。它既可以是你編寫的類也可以是你要添加制定行為的第三方類。如果沒有AOP,這個類就必須要包含它的主要邏輯以及其他交叉業務邏輯。有了AOP,目標對象就可以全身心地關注主要業務,忘記應用其上的通知。
代理(Proxy)
代理是將通知應用到目標對象后創建的對象。對于客戶對象來說,目標對象(應用AOP之前的對象)和代理對象(應用AOP之后的對象)是一樣的。也就是,應用系統的其他部分不用為了支持代理對象而改變。
織入 (Weaving)
織入是將切面應用到目標對象從而創建一個新的代理對象的過程。切面在指定接入點被織入到目標對象中。
二. 幾個重要接口
用于找到用于通知的相關的類型和方法
View Code public interface IPointcut { ITypeFilter TypeFilter { get; } IMethodMatcher MethodMatcher { get; } }
用于匹配相關類型
View Code public interface ITypeFilter { bool Matches(Type type); } public interface IMethodMatcher { bool IsRuntime { get; } bool Matches(MethodInfo method, Type targetType); bool Matches(MethodInfo method, Type targetType, object[] args); }
Matches(MethodInfo, Type)方法用來測試這個切入點是否匹配目標類的指定方法。這將在AOP代理被創建的時候執行,這樣可以避免在每次方法調用的時候都執行。如果兩個參數的matches方法對于一個給定的方法返回true,并且IMethodMatcher接口的IsRuntime方法也返回true,那么有三個參數的matches方法將在每個方法調用時被調用. 這使得切入點在通知將被執行前可以查看傳入到方法的參數。
絕大多數的IMethodMatcher接口是static的,這也就意味著它們的IsRuntime屬性返回false.在這種情況下,有三個參數的Matches方法將永遠不會被調用.
三. 通知
3.1 通知生命周期
3.2 通知類型
一、攔截環繞通知(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接口。后置通知對切入點的執行沒有影響,如果通知拋出異常,就會沿攔截器鏈向上拋出,從而中斷攔截器鏈的繼續執行。
3.2.1 Interception Around Advice(環繞攔截通知,后面的講解以環繞攔截通知為例子)
方法攔截器接口
View Code public interface IMethodInterceptor : IInterceptor { object Invoke(IMethodInvocation invocation); }
模擬環繞攔截通知
View Code public class DebugInterceptor : IMethodInterceptor { public object Invoke(IMethodInvocation invocation) { Console.WriteLine("Before: invocation=[{0}]", invocation); object rval = invocation.Proceed(); Console.WriteLine("Invocation returned"); return rval; } }
注意 IMethodInvocation 的 Proceed 方法,proceed方法返回方法的返回值.
四. 切入點操作
4.1 靜態切入點
4.1.1 ProxyFactoryObject 顯式創建AOP代理
AOP 配置文件 <object id="UserValidateTarget" type="Stephen.SpringNet.AOPSample.Servcies.Impl.UserValidate, Servcies"></object> <object id="RoundInterceptor" type="Stephen.SpringNet.AOPSample.Servcies.Interceptor.RoundInterceptor, Servcies"></object> <object id="UserValidateProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> <property name="proxyInterfaces" value="Stephen.SpringNet.AOPSample.Servcies.IValidateService"/> <property name="target" ref="UserValidateTarget"/> <property name="interceptorNames"> <list> <value>RoundInterceptor</value> </list> </property> </object>
不過由于顯式的創建AOP在要創建多個代理的時候需要重復的配置因此Spring提供了自動代理
4.1.2 ObjectNameAutoProxyCreator 對象名稱自動切入點
可以用特定的文本值或通配符匹配目標對象的名稱,并為滿足條件的目標對象創建AOP代理。該類支持模式匹配字符串,如:"*name","name*",”*name*“和精確文本如"name"。我們可以通過下面這個簡單的例子了解一下自動代理的功能。
AOP 配置文件 <object id="IValidateProxy" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop"> <property name="ObjectNames"> <list> <value>*Validate</value> </list> </property> <property name="InterceptorNames" value="RoundInterceptor"></property> </object>
測試方法 [TestMethod] public void ObjectNameAutoProxyCreatorMethodTest() { var context = ContextRegistry.GetContext(); IDictionary validates = context.GetObjectsOfType(typeof(IValidateService)); foreach (DictionaryEntry validate in validates) { ((IValidateService) validate.Value).Validate(null); } }
執行結果
ObjectNameAutoProxyCreatorMethodTest : Passed
Method:Validate開始執行
Method:Validate執行完畢
4.1.3 SdkRegularExpressionMethodPointcut 通過正則表達式來匹配需要執行的類或方法
AOP 配置 <object id="ValidatePointCut" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop"> <property name="Pattern" value="UserValidate.Advance*"></property> </object> <aop:config> <aop:advisor advice-ref="RoundInterceptor" pointcut-ref="ValidatePointCut"/> </aop:config>
pattern 的屬性 UserValidate.Advance* 表示 匹配 UserValidate 類中的以Advance開頭的方法
4.1.4 DefaultAdvisorAutoProxyCreator+RegularExpressionMethodPointcutAdvisor 創建正則表達式AOP
AOP 配置 <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/> <object id="ValidateRegularExpressionPointCut" type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop"> <property name="advice" ref="RoundInterceptor"/> <property name="patterns"> <list> <value>UserValidate.Advance*</value> </list> </property> </object>
4.1.5 特性Aop
可以通過Attribute類來實現AOP
[AttributeUsage(AttributeTargets.Method)] public class AopAttribute:Attribute { }
AOP 配置 <object id="aroundAdvisor" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop"> <property name="Advice" ref="RoundInterceptor"/> <property name="Attribute" value ="Stephen.SpringNet.AOPSample.Servcies.AopAttribute, Servcies" /> </object> <object id="ValidateAttributeProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> <property name="proxyInterfaces" value="Stephen.SpringNet.AOPSample.Servcies.IValidateService"/> <property name="target" ref="UserValidateTarget"/> <property name="interceptorNames"> <list> <value>aroundAdvisor</value> </list> </property> </object>
看完上述內容,你們對Spring.net中怎么實現Aop編程有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。