<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Spring.Net實現AOP以及AOP相關概念(學習筆記四)

        Spring的重要應用是在AOP(Aspect- Oriented programming面向方面編程)編程方面。Spring.Net是如何進行AOP的呢?下面是我在學習Spring實現AOP的例子以及我個人的一些淺顯的理解,若有不妥之處,還望大俠們指出。

        本節重點分如下兩部分:

        1、Spring實現AOP。

        2、AOP相關概念。

        先介紹如何實現AOP,然后再通過使用過程中的用法,談談我自己對AOP概念的理解。

        首先還是介紹一下開發環境以及軟件版本:

        VS版本:VS2008 SP1、Spring版本:1.3.0。

        在我使用Spring.Net實現AOP的例子中有兩個部分:1、使用編程方式實現。2、使用配置方式實現。實際在應用中,應用配置實現AOP還是相對更好點。實現AOP除了之前用到的程序集以外,還需使用程序集Spring.AOP。

        1、Spring實現AOP

        先說說編程實現的方式。這種方式當然不需要配置文件。主要應用了程序集Spring.Net中Spring.Aop.Framework命名空間下的ProxyFactory(代理工廠)類。

        先給出需要進行攔截的對象的代碼:

       

      代碼
      1 public interface ICommand
      2 {
      3 object Execute(object context);
      4
      5 }
      6 public class BusinessCommand : ICommand
      7 {
      8 public object Execute(object context)
      9 {
      10 Console.WriteLine("Service implementation is :{0}", context);
      11 return context;
      12 }
      13
      14 }

        下面是實現對 BusinessCommand攔截的實現代碼:

       

      代碼
      1public class ConsoleLoggingAroundAdvice : IMethodInterceptor
      2 {
      3 public object Invoke(IMethodInvocation invocation)
      4 {
      5 Console.WriteLine("Method in ConsoleLoggingAroundAdvice");
      6
      7 object obj = invocation.Proceed();
      8 Console.WriteLine("invocation type is :{0}", invocation.GetType().ToString());
      9 Console.WriteLine("Method name is {0}", invocation.Method.ToString());
      10 return obj;
      11 }
      12 }
      在上述攔截實現類中,我使用了環繞攔截。當然還有其他的攔截方式,以后會說到。我讓ConsoleLoggingAroundAdvice類繼承了Spring.AOP程序集下的AopAlliance.Intercept命名控件中的IMethodInterceptor,并中其中實現了接口的 object Invoke(IMethodInvocation invocation)方法。

        在這個例子中,我測試一下Spring.Net對Execute方法的攔截。使用代碼如下:

      代碼
      1 ICommand target = new BusinessCommand();
      2 ProxyFactory factory = new ProxyFactory(target);
      3 factory.AddAdvice(new ConsoleLoggingAroundAdvice());
      4 object obj = factory.GetProxy();
      5
      6
      7 ICommand business = (ICommand)obj;
      8 Console.WriteLine(obj.GetType().ToString());
      9 //ICommand command = (ICommand)factory.GetProxy();
      10 business.Execute("tyb");
      11 target.Execute("This is the argument");
      說明:target.Execute("This is the argument");與攔截沒有關系,即不會對 Execute方法進行攔截。后面我會說說為什么沒有進行攔截的理解。

        輸出如下圖:


        從以上輸出可以看到:我只是通過business.Execute("tyb")與 target.Execute("This is the argument")進行了輸出。但是兩條輸出的執行方式是不一樣的。顯然后者輸出的最后一條顯示的結果。前者的輸出結果為前5行。如果我用斷點調試,則進行到ConsoleLoggingAroundAdvice中的Invoke方法。所以前一條輸出了5行。為什么兩條輸出的結果會有這么大的差別呢?

        business、target兩者都是實現了ICommand接口對象的實例,而前者是通過代理工廠(ProxyFactory)獲取代理(GetProxy)的方式實現的,后者則不一樣。我的理解是:

        通過factory.GetProxy()將攔截應用到了ICommand上,而target是直接通過new生成的,所以就沒有將通知應用到target。

        在輸出的第一行中,輸出了object obj = factory.GetProxy()中obj的類型。它也可以轉換為ICommand,說明它也是實現了ICommand的。那么如果我們將ICommand business = (ICommand)obj中將ICommand用實現它的類BusinessCommand類替換成BusinessCommand business = (BusinessCommand)obj,是不是就不能正常運行了呢?答案是肯定的。運行過程中跑出如下異常:

        由以上試驗我們可推理:在應用攔截的對象中,攔截對象應該要實現一個接口。是不是這樣呢。?我繼續添加了ServiceCommand類,代碼如下:

       

      代碼
      1 public class ServiceCommand
      2 {
      3 public object Execute(object context)
      4 {
      5 Console.WriteLine("Service implementation is :{0}", context);
      6 return context;
      7 }
      8 }
      代碼
      1 ServiceCommand command2 = new ServiceCommand();
      2 ProxyFactory factory2 = new ProxyFactory(command2);
      3 factory2.AddAdvice(new ConsoleLoggingAroundAdvice());
      4 ServiceCommand command3 = (ServiceCommand)factory2.GetProxy();
      5 command3.Execute("tyb");

      輸出如下圖:

       

        由以上輸出,我可以得知,根本就沒有進行攔截。

        注意:以上實現過程中,需要將接口申明為public類型的,即在給ProxyFactory的構造函數中給出對象的類型聲明,不管是接口還是類對象,都必須是public的。

        接口為private類型時,在類型轉換的時候會有如下異常:

        如果上例中的ServiceCommand未private類型的會有異常。但是和接口所拋出的不一樣,有興趣大家可以試試。

        說完了編程實現AOP,下面說說通過配置的方式實現。

        配置實現AOP。

        配置方式實現AOP通過配置的方式以及IOC容器獲取對象的方式實現。在IOC容器的配置中,被攔截BusinessCommand類的定義是代理工廠對象(ProxyFactoryObject).

        配置如下:

       

      代碼
      1 <objects xmlns="http://www.springframework.net" xmlns:aop="http://www.springframework.net/aop">
      2
      3 <object id="myServiceObject" type="Spring.Aop.Framework.ProxyFactoryObject">
      4 <property name="Target" >
      5 <object id="businessCommand" type="SpringAOPConfig.BusinessCommand"/>
      6 </property>
      7 <property name="InterceptorNames">
      8 <list>
      9 <value>consoleLoggingAroundAdvice</value>
      10 </list>
      11 </property>
      12 </object>
      13
      14
      15 <object id="consoleLoggingAroundAdvice" type="SpringAOPConfig.ConsoleLoggingAroundAdvice"/>
      16
      17
      18 </objects>

      其他接口定義以及類實現同編程實現的方式大致相同,只是在攔截類定義中,實現IMethodInterceptor接口中的Invoke(IMethodInvocation invocation)方法時,只調用了object obj = invocation.Proceed()。

       

        此時的使用方式如下:

       

      代碼
      1 IApplicationContext context = ContextRegistry.GetContext();
      2
      3 //command2.Execute();
      4  
      5 object obj = context.GetObject("myServiceObject");
      6 ICommand command = (ICommand)context.GetObject("myServiceObject");
      7 command.Execute("tyb");
      8
      9 Console.WriteLine();
      10
      11 ICommand command2 = (ICommand)context["myServiceObject"];
      12 command2.Execute("taoyongbo");
      13 //command.Execute();
      14   IDictionary dic = context.GetObjectsOfType(typeof(ICommand));
      15 foreach (DictionaryEntry item in dic)
      16 {
      17 Console.WriteLine("key is: {0},value is :{1}", item.Key, item.Value);
      18 }

        首先過容器獲取定義的對象后,通過類型轉換后直接使用。

       

        輸出結果如下圖:

        這樣就實現了和編程方式一樣的效果。問題是上述的方式只是對ICommand中的Execute方法進行了攔截,如果還要對接口中的其他方法進行攔截怎么辦呢。?

        我們只需在ICommand中定義另一個方法就行了。定義如下:

       

      1 public interface ICommand
      2 {
      3 object Execute(object context);
      4
      5 object Execute();
      6 }

        這樣就實現了對接口中所有方法的攔截。

       

        假設我們還要將攔截應用到其他的類上,那么我們該如何實現呢。?新的接口定義與被攔截類的定義和第一個沒什么區別,我這里就不在給出了,大家有興趣可以下載代碼了看看就行了。我主要給出配置文件。

       

      代碼
      1 <objects xmlns="http://www.springframework.net" xmlns:aop="http://www.springframework.net/aop">
      2
      3 <object id="myServiceObject" type="Spring.Aop.Framework.ProxyFactoryObject">
      4 <property name="Target" >
      5 <object id="businessCommand" type="SpringAOPConfig.BusinessCommand"/>
      6 </property>
      7 <property name="InterceptorNames">
      8 <list>
      9 <value>consoleLoggingAroundAdvice</value>
      10 </list>
      11 </property>
      12 </object>
      13
      14 <object id="myServiceObject1" type="Spring.Aop.Framework.ProxyFactoryObject">
      15 <property name="Target">
      16 <object type="SpringAOPConfig.BusinessTest" />
      17 </property>
      18 <property name="InterceptorNames">
      19 <list>
      20 <value>consoleLoggingAroundAdvice</value>
      21 </list>
      22 </property>
      23 </object>
      24
      25 <object id="consoleLoggingAroundAdvice" type="SpringAOPConfig.ConsoleLoggingAroundAdvice"/>

        由配置可以看出,新增的被攔截類的配置通前一個除了名稱以外,其他都一樣。

        使用方式如下:

      代碼
      1 IApplicationContext context = ContextRegistry.GetContext();
      2
      3
      4
      5 object obj = context.GetObject("myServiceObject");
      6 ICommand command = (ICommand)context.GetObject("myServiceObject");
      7 command.Execute("tyb");
      8 command.Execute();
      9
      10 Console.WriteLine();
      11
      12 ICommand command2 = (ICommand)context["myServiceObject"];
      13 command2.Execute("taoyongbo");
      14 command2.Execute();
      15
      16 IDictionary dic = context.GetObjectsOfType(typeof(ICommand));
      17 foreach (DictionaryEntry item in dic)
      18 {
      19 Console.WriteLine("key is: {0},value is :{1}", item.Key, item.Value);
      20 }
      21
      22 //IApplicationContext ctx = ContextRegistry.GetContext();
      23 //BusinessCommand command = (BusinessCommand)ctx["myServiceObject"];
      24 //command.Execute();
      25
      26 //IApplicationContext context = ContextRegistry.GetContext();
      27   ITest business = (ITest)context["myServiceObject1"];
      28
      29 business.Fun1();
      30
      31 Console.Read();
      運行結果如下圖:

        對配置文件的幾點總結:

        一、在進行攔截時,都定義為由Spring.Aop.Framework.ProxyFactoryObject來處理。

        二、名稱為Target的屬性,定義為目標對象類型。

        三、屬性為InterceptorNames的值,定義方面(Aspects)。

         當然,通過配置方式實現AOP時,也需要將接口聲明為public,以及在獲取到目標代理對象的時候,只能通過接口來進行類型轉換,這點和編程實現AOP是一致的。

        2、AOP相關概念

        1、方面(Aspects):對橫向分布在多個對象中的關注點所作的模塊化。在企業應用中事務管理就是一個典型的橫切關注點。在Spring.Net中,將方面實現為Advisor或攔截器(Interceptor)。Advisor一般是通知和切入點的組合。攔截器實際上就是指通知。Spring.Net中一般把環繞通知成為攔截器, 而其他類型的通知成為通知。因為環繞通知實現的是AopAlliance.Intercept.IMethodInterceptor接口,而其他類型通知實現的是Spring.AOP命名控件下的其他接口。如ConsoleLoggingAroundAdvice

        2、連接點(joinPoint):程序過程中的一個點。如程序中的方法。如:BusinessCommand中的Execute方法。

        3、通知(Advice):AOP框架在某個連接點(方法)中所采取的行為。通知有很多類型:如環線通知、前置通知、后置通知、異常通知。如:ConsoleLoggingAroundAdvice中public object Invoke(IMethodInvocation invocation)所執行的代碼

        4、切入點(PointCut):指通知的應用條件,用于確定某個通知應用到那個連接點(方法)上。AOP框架允許程序員自己定義切入點,也可以在定義中使用正則表達式定義。如:object id="myServiceObject"節點的定義

        5、引入(Introduction):向目標對象添加字段或方法的行為。Spring.Net允許為目標對象引入新的接口。如:可以利用引入讓任何對象在運行期間實現IAuditable接口,以簡化對象狀態變化的跟蹤過程。如程序中使用:factory.AddAdvice(new ConsoleLoggingAroundAdvice())將通知應用到目標對象上。

        6、目標對象(Target Object ):包辦連接點的對象。也被稱為被通知或被代理對象。如:BusinessCommand

        7、AOP代理(AOP Proxy):由AOP框架在將通知應用于目標對象后創建的對象。在Spring.Net中是使用IL代碼在運行期創建的動態代理。如:程序中使用的object obj = factory.GetProxy()中。

        8、織入(Weaving):將方面進行組裝,以創建一個目標對象。它可以在編譯期間完成,也可以在運行期完成。Spring在運行時執行織入??椚缡且粋€過程,如程序中ProxyFactory factory = new ProxyFactory(target); factory.AddAdvice(new ConsoleLoggingAroundAdvice());    object obj = factory.GetProxy();的執行。

        以上就是我對Spring.Net中AOP的理解。要什么不妥指出,還望不吝賜教!

      代碼下載:Spring.Net AOP DEMO

      參考文檔:Spring.Net框架參考手冊

             http://www.rzrgm.cn/GoodHelper/archive/2009/11/13/SpringNet_Aop_Concept.html

        

       

      posted @ 2010-12-10 15:58  tyb1222  閱讀(2541)  評論(5)    收藏  舉報
      主站蜘蛛池模板: AV秘 无码一区二| 国产大学生粉嫩无套流白浆| 久久午夜无码鲁丝片直播午夜精品| 亚洲av无码牛牛影视在线二区| 337p粉嫩大胆噜噜噜| 久久精品无码av| 老熟妇老熟女老女人天堂| 久久综合亚洲色一区二区三区| 国产精品综合av一区二区国产馆| 久久国产免费观看精品3| 熟女激情乱亚洲国产一区| 免费观看在线A级毛片| 久久这里有精品国产电影网| 久久精品免视看国产成人| 免费VA国产高清大片在线| аⅴ天堂中文在线网| 18禁视频一区二区三区| 免费观看全黄做爰大片| 玩两个丰满老熟女久久网| 亚洲av无码之国产精品网址蜜芽| 狠狠色婷婷久久综合频道日韩| 国产69精品久久久久乱码免费| 亚洲中文字幕在线二页| 国产漂亮白嫩美女在线观看| 精品国产精品中文字幕| 欧美巨大极度另类| 野花社区在线观看视频| 久久久久无码精品国产h动漫| 伊人久久大香线蕉成人| 东光县| 日本一区二区三区小视频| 换着玩人妻中文字幕| 一区二区三区精品不卡| 免费人成在线观看网站| 久久精品国产久精国产69| 国产午精品午夜福利757视频播放| 亚洲男人天堂一级黄色片| 无码中文字幕热热久久| 国产av一区二区久久蜜臀| 国精偷拍一区二区三区| 国产精品无码av不卡|