自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺析Spring.net中的Aop使用

開(kāi)發(fā) 架構(gòu)
AOP為Aspect Oriented Programming的縮寫(xiě),意為:面向切面編程(也叫面向方面),可以通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加 功能的一種技術(shù)。

一. 什么是AOP

AOP為Aspect Oriented Programming的縮寫(xiě),意為:面向切面編程(也叫面向方面),可以通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加 功能的一種技術(shù)。AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP可以說(shuō)也是這種目標(biāo)的一種實(shí)現(xiàn)。

主要的功能是:日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等等。

主要的意圖是:將日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來(lái),通過(guò)對(duì)這些行為的分離,我們希望可以將它們獨(dú)立到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進(jìn)而改變這些行為的時(shí)候不影響業(yè)務(wù)邏輯的代碼。

可以通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加功能的一種技術(shù)。AOP實(shí)際是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式孜孜不倦追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP可以說(shuō)也是這種目標(biāo)的一種實(shí)現(xiàn)。

在Spring中提供了面向切面編程的豐富支持,允許通過(guò)分離應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)級(jí)服務(wù)(例 如審計(jì)(auditing)和事務(wù)(transaction)管理)進(jìn)行內(nèi)聚性的開(kāi)發(fā)。應(yīng)用對(duì)象只實(shí)現(xiàn)它們應(yīng)該做的——完成業(yè)務(wù)邏輯——僅此而已。它們并 不負(fù)責(zé)(甚至是意識(shí))其它的系統(tǒng)級(jí)關(guān)注點(diǎn),例如日志或事務(wù)支持。

          切面(Aspect)

切面是你要實(shí)現(xiàn)的交叉功能。它是應(yīng)用系統(tǒng)模塊化的一個(gè)切面或領(lǐng)域。切面的最常見(jiàn)(雖然簡(jiǎn)單)例子是日志記錄。日志記錄在系統(tǒng)中到處需要用到,利用繼承來(lái)重用日志模塊不適合。然而,你可以創(chuàng)建一個(gè)日志記錄切面,并且使用AOP在系統(tǒng)中應(yīng)用。

連接點(diǎn)(Joinpoint)

連接點(diǎn)是應(yīng)用程序執(zhí)行過(guò)程中插入切面的地點(diǎn)。這個(gè)地點(diǎn)可以是方法調(diào)用,異常拋出,或者甚至是要修改的字段。切面代碼在這些地方插入到你的應(yīng)用流程中,添加新的行為。

通知(Advice)

通知切面的實(shí)際實(shí)現(xiàn)。它通知應(yīng)用系統(tǒng)新的行為。在日志例子中,日志通知包含了實(shí)現(xiàn)實(shí)際日志功能的代碼,如向日志文件寫(xiě)日志。通知在連接點(diǎn)插入到應(yīng)用系統(tǒng)中。

切入點(diǎn)(Pointcut)

切入點(diǎn)定義了通知應(yīng)該應(yīng)用在哪些連接點(diǎn)。通知可以應(yīng)用到AOP框架支持的任何連接點(diǎn)。當(dāng)然,你并不希望把所有切面應(yīng)用到所有可能的連接點(diǎn)上。切入點(diǎn)讓你指定通知應(yīng)用到什么地方。通常通過(guò)指定類(lèi)名和方法名,或者匹配類(lèi)名和方法名式樣的正則表達(dá)式來(lái)指定切入點(diǎn)。一些AOP框架允許動(dòng)態(tài)創(chuàng)建切入點(diǎn),在運(yùn)行時(shí)根據(jù)條件決定是否應(yīng)用切面,如方法參數(shù)值。

引入(Introduction)

引入允許你為已存在類(lèi)添加新方法和屬性。例如,你可以創(chuàng)建一個(gè)稽查通知來(lái)記錄對(duì)象的***修改時(shí)間。只要用一個(gè)方法setLastMofified(Date)以及一個(gè)保存這個(gè)狀態(tài)的變量。可以在不改變已存在類(lèi)的情況下將這個(gè)引入,給他們新的行為和狀態(tài)。

目標(biāo)對(duì)象(Target)

目標(biāo)對(duì)象是被通知對(duì)象。它既可以是你編寫(xiě)的類(lèi)也可以是你要添加制定行為的第三方類(lèi)。如果沒(méi)有AOP,這個(gè)類(lèi)就必須要包含它的主要邏輯以及其他交叉業(yè)務(wù)邏輯。有了AOP,目標(biāo)對(duì)象就可以全身心地關(guān)注主要業(yè)務(wù),忘記應(yīng)用其上的通知。

代理(Proxy)

代理是將通知應(yīng)用到目標(biāo)對(duì)象后創(chuàng)建的對(duì)象。對(duì)于客戶對(duì)象來(lái)說(shuō),目標(biāo)對(duì)象(應(yīng)用AOP之前的對(duì)象)和代理對(duì)象(應(yīng)用AOP之后的對(duì)象)是一樣的。也就是,應(yīng)用系統(tǒng)的其他部分不用為了支持代理對(duì)象而改變。

織入 (Weaving)

織入是將切面應(yīng)用到目標(biāo)對(duì)象從而創(chuàng)建一個(gè)新的代理對(duì)象的過(guò)程。切面在指定接入點(diǎn)被織入到目標(biāo)對(duì)象中。

二. 幾個(gè)重要接口 

用于找到用于通知的相關(guān)的類(lèi)型和方法

  1. View Code   
  2.  public interface IPointcut  
  3.    
  4.  {  
  5.    
  6.      ITypeFilter TypeFilter { get; }  
  7.    
  8.      IMethodMatcher MethodMatcher { get; }  
  9.    
  10.  } 

用于匹配相關(guān)類(lèi)型

  1. View Code   
  2.  public interface ITypeFilter  
  3.    
  4.  {  
  5.    
  6.      bool Matches(Type type);  
  7.    
  8.  }  
  9.    
  10.  public interface IMethodMatcher  
  11.    
  12.  {  
  13.    
  14.      bool IsRuntime { get; }  
  15.    
  16.      bool Matches(MethodInfo method, Type targetType);  
  17.    
  18.      bool Matches(MethodInfo method, Type targetType, object[] args);  
  19.    
  20.  } 

Matches(MethodInfo, Type)方法用來(lái)測(cè)試這個(gè)切入點(diǎn)是否匹配目標(biāo)類(lèi)的指定方法。這將在AOP代理被創(chuàng)建的時(shí)候執(zhí)行,這樣可以避免在每次方法調(diào)用的時(shí)候都執(zhí)行。如果兩個(gè)參數(shù)的matches方法對(duì)于一個(gè)給定的方法返回true,并且IMethodMatcher接口的IsRuntime方法也返回true,那么有三個(gè)參數(shù)的matches方法將在每個(gè)方法調(diào)用時(shí)被調(diào)用. 這使得切入點(diǎn)在通知將被執(zhí)行前可以查看傳入到方法的參數(shù)。

絕大多數(shù)的IMethodMatcher接口是static的,這也就意味著它們的IsRuntime屬性返回false.在這種情況下,有三個(gè)參數(shù)的Matches方法將永遠(yuǎn)不會(huì)被調(diào)用.

三. 通知

3.1 通知生命周期

3.2 通知類(lèi)型

一、攔截環(huán)繞通知(around advice):Spring.NET中最基本的通知類(lèi)型是攔截環(huán)繞通知(interception around advice),即方法攔截器。攔截環(huán)繞通知繼承IMethodInterceptor接口。注意其中IMethodInvocation.Proceed()方法的調(diào)用。該方法會(huì)依次調(diào)用攔截器鏈上的其它攔截器。大部分?jǐn)r截器都需要調(diào)用這個(gè)方法并返回它的返回值。當(dāng)然,也可以不調(diào)用Proceed方法,而返回一個(gè)其它值或拋出一個(gè)異常,但一般不太會(huì)這么做。

二、前置通知(before advise):是在IMethodInterceptor.Proceed()方法調(diào)用前的通知。繼承自IMethodBeforeAdvice接口。

三、異常通知(throws advise):是在IMethodInterceptor.Proceed()方法調(diào)用時(shí)發(fā)生異常的通知。繼承自IthrowsAdvice接口。IthrowsAdvice接口沒(méi)有定義任何方法:它是一個(gè)標(biāo)識(shí)接口(按:之所以用標(biāo)識(shí)接口,原因有二:1、在通知方法中,只有***一個(gè)參數(shù)是必須的。如果聲明為接口的方法,參數(shù)列表就被固定了。2、如果***個(gè)原因可以用重載的接口方法解決,那么這個(gè)原因就是使用標(biāo)識(shí)接口的充分原因了:實(shí)現(xiàn)此接口的類(lèi)必須聲明一或多個(gè)通知方法,接口方法做不到這一點(diǎn)),用以表明實(shí)現(xiàn)它的類(lèi)聲明了一或多個(gè)強(qiáng)類(lèi)型的異常通知方法。

四、后置通知(after returning advise):是在IMethodInterceptor.Proceed()方法調(diào)用后的通知。繼承自IAfterReturningAdvice接口。后置通知對(duì)切入點(diǎn)的執(zhí)行沒(méi)有影響,如果通知拋出異常,就會(huì)沿?cái)r截器鏈向上拋出,從而中斷攔截器鏈的繼續(xù)執(zhí)行。

3.2.1 Interception Around Advice(環(huán)繞攔截通知,后面的講解以環(huán)繞攔截通知為例子)

方法攔截器接口

  1. View Code   
  2.  public interface IMethodInterceptor : IInterceptor  
  3.    
  4.  {  
  5.    
  6.      object Invoke(IMethodInvocation invocation);  
  7.    
  8.  } 

模擬環(huán)繞攔截通知

  1. View Code   
  2.  public class DebugInterceptor : IMethodInterceptor   
  3.  {  
  4.    
  5.      public object Invoke(IMethodInvocation invocation)   
  6.  {  
  7.    
  8.          Console.WriteLine("Before: invocation=[{0}]", invocation);  
  9.    
  10.          object rval = invocation.Proceed();  
  11.    
  12.          Console.WriteLine("Invocation returned");  
  13.    
  14.          return rval;  
  15.    
  16.      }  
  17.    
  18.  } 

注意 IMethodInvocation 的 Proceed 方法,proceed方法返回方法的返回值.

四. 切入點(diǎn)操作

4.1 靜態(tài)切入點(diǎn)

4.1.1 ProxyFactoryObject 顯式創(chuàng)建AOP代理

  1. AOP 配置文件  
  2.  <object id="UserValidateTarget" type="Stephen.SpringNet.AOPSample.Servcies.Impl.UserValidate, Servcies"></object> 
  3.    
  4.    <object id="RoundInterceptor" type="Stephen.SpringNet.AOPSample.Servcies.Interceptor.RoundInterceptor, Servcies"></object>   
  5.    
  6.    <object id="UserValidateProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> 
  7.    
  8.      <property name="proxyInterfaces" value="Stephen.SpringNet.AOPSample.Servcies.IValidateService"/> 
  9.    
  10.      <property name="target" ref="UserValidateTarget"/> 
  11.    
  12.      <property name="interceptorNames"> 
  13.    
  14.        <list> 
  15.    
  16.          <value>RoundInterceptor</value> 
  17.    
  18.        </list> 
  19.    
  20.      </property> 
  21.    
  22.    </object> 

不過(guò)由于顯式的創(chuàng)建AOP在要?jiǎng)?chuàng)建多個(gè)代理的時(shí)候需要重復(fù)的配置因此Spring提供了自動(dòng)代理

4.1.2 ObjectNameAutoProxyCreator 對(duì)象名稱(chēng)自動(dòng)切入點(diǎn)

可以用特定的文本值或通配符匹配目標(biāo)對(duì)象的名稱(chēng),并為滿足條件的目標(biāo)對(duì)象創(chuàng)建AOP代理。該類(lèi)支持模式匹配字符串,如:"*name","name*",”*name*“和精確文本如"name"。我們可以通過(guò)下面這個(gè)簡(jiǎn)單的例子了解一下自動(dòng)代理的功能。

  1. AOP 配置文件  
  2.  <object id="IValidateProxy" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">  
  3.      <property name="ObjectNames">  
  4.        <list>  
  5.          <value>*Validate</value>  
  6.        </list>  
  7.      </property>     
  8.      <property name="InterceptorNames" value="RoundInterceptor"></property>  
  9.    </object
  1. 測(cè)試方法  
  2.  [TestMethod]  
  3.          public  void ObjectNameAutoProxyCreatorMethodTest()  
  4.          {  
  5.              var context = ContextRegistry.GetContext();  
  6.              IDictionary validates = context.GetObjectsOfType(typeof(IValidateService));  
  7.              foreach (DictionaryEntry validate in validates)  
  8.              {  
  9.                  ((IValidateService) validate.Value).Validate(null);  
  10.    
  11.              }  
  12.          } 

執(zhí)行結(jié)果

ObjectNameAutoProxyCreatorMethodTest : Passed

Method:Validate開(kāi)始執(zhí)行

Method:Validate執(zhí)行完畢

 

4.1.3 SdkRegularExpressionMethodPointcut 通過(guò)正則表達(dá)式來(lái)匹配需要執(zhí)行的類(lèi)或方法

  1. AOP 配置  
  2.  <object id="ValidatePointCut" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop"> 
  3.      <property name="Pattern" value="UserValidate.Advance*"></property> 
  4.    </object> 
  5.    <aop:config> 
  6.      <aop:advisor advice-ref="RoundInterceptor" pointcut-ref="ValidatePointCut"/> 
  7.    </aop:config> 

pattern 的屬性 UserValidate.Advance* 表示 匹配 UserValidate 類(lèi)中的以Advance開(kāi)頭的方法

 

4.1.4 DefaultAdvisorAutoProxyCreator+RegularExpressionMethodPointcutAdvisor 創(chuàng)建正則表達(dá)式AOP

  1. AOP 配置  
  2.  <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>  <object id="ValidateRegularExpressionPointCut" type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop"> 
  3.      <property name="advice" ref="RoundInterceptor"/> 
  4.      <property name="patterns"> 
  5.        <list> 
  6.          <value>UserValidate.Advance*</value> 
  7.        </list> 
  8.      </property> 
  9.    </object> 

4.1.5 特性Aop

可以通過(guò)Attribute類(lèi)來(lái)實(shí)現(xiàn)AOP

  1. [AttributeUsage(AttributeTargets.Method)]  
  2.    public class AopAttribute:Attribute  
  3.  
  4.     {    
  5.  
  6.     } 
  1. AOP 配置  
  2.   <object id="aroundAdvisor" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop"> 
  3.      <property name="Advice" ref="RoundInterceptor"/> 
  4.      <property name="Attribute" 
  5.                 value ="Stephen.SpringNet.AOPSample.Servcies.AopAttribute, Servcies" /> 
  6.    </object> 
  7.    <object id="ValidateAttributeProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> 
  8.      <property name="proxyInterfaces" value="Stephen.SpringNet.AOPSample.Servcies.IValidateService"/> 
  9.      <property name="target" ref="UserValidateTarget"/> 
  10.      <property name="interceptorNames"> 
  11.        <list> 
  12.          <value>aroundAdvisor</value> 
  13.        </list> 
  14.      </property> 
  15.    </object> 

原文鏈接:http://www.cnblogs.com/vipyoumay/archive/2012/07/07/2580420.html

責(zé)任編輯:林師授 來(lái)源: 博客園
相關(guān)推薦

2009-06-22 11:48:08

Spring.NET

2009-06-19 11:09:27

Spring AOP

2009-07-29 14:12:45

ASP.NET tra

2009-03-13 13:46:41

.NETServer push服務(wù)端

2019-11-29 16:21:22

Spring框架集成

2009-11-03 13:48:02

VB.NET枚舉

2009-08-03 10:07:20

ASP.NET Ses

2009-08-10 14:55:43

ASP.NET htt

2021-03-01 23:26:41

日志Spring BootAOP

2024-03-25 03:00:00

.NET 6await編程

2009-12-24 14:30:56

VB.NET

2009-07-22 14:23:39

URL RewriteASP.NET

2009-11-13 10:10:07

2009-10-13 15:20:02

VB.NET使用Dra

2009-10-16 14:07:18

VB.NET使用Mon

2009-11-12 10:06:01

ADO.NET讀取數(shù)據(jù)

2009-11-04 09:18:12

ADO.NET _Re

2009-07-29 13:42:25

ASP.NET注釋

2009-04-08 09:58:07

ASP.NET MVCTempData框架

2009-07-27 09:29:38

ASP.NET中Jav
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)