AOP系列(一)——ProxyFactoryObject 顯式建立AOP代理

來源:互聯網
上載者:User

標籤:aop   代理   

AOP概念

  Aspect Oriented Programming,面向切面編程,可以通過先行編譯方式和運行期動態代理,實現在不修改原始碼的情況下給程式動態統一添加功能的一種技術。

前提


  • 瞭解Spring.NET IOC
  • 熟悉代理模式

  下面我們結合一個具體的例子來瞭解AOP。

基本情景

User類

    /// <summary>    /// 使用者實體,具有姓名和年齡兩個屬性    /// </summary>    public class User    {        public string Name { get; set; }        public int Age { get; set; }    }

IUserService

    public interface IUserService    {        //獲得使用者資訊        void GetUserInfo(User enUser);    }

UserService

    public class UserService:IUserService    {        /// <summary>        /// 獲得使用者的資訊        /// </summary>        /// <param name="enUser">使用者實體</param>        public void GetUserInfo(User enUser)        {            //輸出使用者的姓名和年齡            Console.WriteLine("姓名:"+enUser .Name+"年齡:"+enUser .Age  );        }    }

用戶端(控制台應用程式)Program

  • “ new()”出具體的實現——這裡我們不採用此方式
    class Program    {        static void Main(string[] args)        {            //執行個體化一個實體            User enUser = new User()            {                Name = "Danny",                Age = 15            };                       IUserService userService = new UserService();            userService.GetUserInfo(enUser);        }    }
  • 通過Spring IOC獲得具體實現(相當於工廠)
//引入Spring.Core.dllusing Spring.Context;using Spring.Context.Support;namespace WithoutAOP{    class Program    {        static void Main(string[] args)        {            //執行個體化一個實體            User enUser = new User()            {                Name = "Danny",                Age = 15            };                      //獲得Spring.IOC容器的上下文            IApplicationContext context = ContextRegistry.GetContext();            //根據設定檔中的配置獲得業務實作類別            IUserService userService = (IUserService)context.GetObject("userService");            //調用業務實作類別的方法            userService.GetUserInfo(enUser);        }    }}

設定檔

    <!--Spring配置-->    <configSections>        <sectionGroup name="spring">            <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>            <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>        </sectionGroup>    </configSections>    <spring>        <context>            <resource uri="config://spring/objects"/>        </context>        <objects xmlns="http://www.springframework.net">            <object id="userService" type="AOPExample.UserService,AOPExample"/>        </objects>    </spring>

  現在我們要為已有的商務邏輯增加日誌功能。接下來看看AOP如何來實現。
  在瞭解之前,我們先來瞭解AOP中的一些術語。

AOP術語

  • 目標對象(Target),即我們要代理的對象(UserService),也就是我們要為此對象增加日誌功能。
  • 關注點(Concern):如日誌功能。日誌功能是系統層級的,不可能只在一個對象中增加日誌功能。
  • 通知(Advice):在Advice中寫日誌功能的具體實現。通知類實現不同的介面,如:Before,After……這些決定了日誌功能如何添加(切入)到商務邏輯中,是在商務邏輯執行前添加,還是執行後添加。
AOP實現思路
  • 寫具體的通知類Advice(實現日誌功能)
  • 在設定檔中進行配置

    • 配置組建代理程式類的方式
    • 配置目標對象(可以直接配置具體的目標對象,也可以通過名稱或Regex,程式執行後會在容器中尋找到合格對象作為目標對象)

    • 配置通知類

ProxyFactoryObject 顯式建立AOP代理

Advice通知類

//引入System.Aop.dll;using Spring.Aop;       //AOPusing System.Reflection;//反射namespace AOPExample{    /// <summary>    /// Advice通知類:實現日誌功能    /// </summary>    public class LogBeforeAdvice:IMethodBeforeAdvice    {        /// <summary>        /// 實現介面IMethodBeforeAdvice中的Before方法,在目標方法執行前執行Before()        /// </summary>        /// <param name="method">攔截的方法</param>        /// <param name="args">方法的參數</param>        /// <param name="target">攔截的對象</param>        public void Before(MethodInfo method, object[] args, object target)        {            Console.WriteLine("攔截的方法名—>" + method.Name);            Console.WriteLine("目標對象—>" + target);            Console.WriteLine("參數—>");            //如果參數不為空白,遍曆所有參數並輸出            if (args != null)            {                foreach (object arg in args)                {                    Console.WriteLine("\t: " + arg);                }            }          }    }}

設定檔

<?xml version="1.0"?><configuration>    <!--Spring.Context.Support.ContextRegistry 的類型初始值設定項引發異常。-->    <!--注釋掉此配置節,否則會報上述異常-->    <!--<startup>         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />    </startup>-->      <!--Spring配置-->    <configSections>        <sectionGroup name="spring">            <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>            <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>        </sectionGroup>    </configSections>    <spring>        <context>            <resource uri="config://spring/objects"/>        </context>        <objects xmlns="http://www.springframework.net">            <!--配置通知類LogBeforeAdvice-->            <object id="beforeAdvice" type="AOPExample.LogBeforeAdvice,AOPExample"/>                     <!--通過ProxyFactoryObject 顯式建立AOP代理-->            <object id="userServiceProxy" type="Spring.Aop.Framework.ProxyFactoryObject">                <!--指定代理的真實對象-->                <property name="Target">                    <object type="AOPExample.UserService,AOPExample"/>                </property>                <!--指定具體通知類-->                <property name="InterceptorNames">                    <list>                        <!--指定具體通知類,和前面配置的id一致-->                        <value>beforeAdvice</value>                    </list>                </property>            </object>        </objects>    </spring></configuration>

用戶端

    class Program    {        static void Main(string[] args)        {            //執行個體化使用者            User enUser = new User()            {                Name ="Jenny",                Age=15            };            //獲得Spring容器上下文            IApplicationContext context = ContextRegistry.GetContext();            //從設定檔獲得由ProxyFactoryObject產生的代理類            //需要修改用戶端,原來是直接調用真實對象,現在是調用代理            IUserService userServiceProxy = (IUserService)context["userServiceProxy"];            userServiceProxy.GetUserInfo(enUser);        }    }

運行結果

總結
  • 優點:通過ProxyFactoryObject 建立代理類,省去自己手動建立代理類;
  • 缺點1:如果有多個目標對象,每個都需要在設定檔中配置;
  • 缺點2:用戶端調用時,由原來調用目標對象,變成調用代理對象,需要修改用戶端代碼。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

AOP系列(一)——ProxyFactoryObject 顯式建立AOP代理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.