用代理技术实现简单的AOP框架
生活随笔
收集整理的這篇文章主要介紹了
用代理技术实现简单的AOP框架
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在許多的實現AOP框架的技術中,不管是靜態織入還是動態織入,關鍵點在于攔截方法,并在方法中加入預處理和后處理。而實現方法的攔截的一個簡單辦法就是 把類的實例委托給類的真實代理(RealProxy).這樣以來,方法的調用都會被轉換成消息(IMessage),同時該消息作為參數被送到真實代理的 Invoke方法。所以我們相應地改寫Invoke方法,加入預處理和后處理也就OK了。
根據這個思路,可以給出一個簡單的代碼實現:
一,定義方法攔截的接口
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging;
namespace LYG.Share.Interface
{
??? public interface IInterceptor
??? {
??????? void PreProcess(IMessage requestMSG);
??????? void PostProcess(IMessage requestMSG, IMessage returnMSG);
??? }
}
二,真實代理的實現
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Services;
using LYG.Share .Interface ;
namespace LYG.Share.AOP.Proxies
{
??? public abstract class AspectProxy : RealProxy, IInterceptor
??? {
??????? private MarshalByRefObject _target = null;
??????? public AspectProxy()
??????????? : base()
??????? {
??????? }
??????? public AspectProxy(Type serverType)
??????????? : base(serverType)
??????? {
??????? }
?????????????
??????? public void InitProxyTarget(MarshalByRefObject target)
??????? {
??????????? this._target = target;
??????? }
??????? public override IMessage Invoke(IMessage msg)
??????? {
??????????? bool useInterception = false;
??????????? IMethodCallMessage invoke = (IMethodCallMessage)msg;
??????????? foreach (InterceptionAttribute attr in invoke.MethodBase.GetCustomAttributes(false))
??????????? {
??????????????? if (attr != null)
??????????????? {
??????????????????? if (attr.UseInterception)
??????????????????? {
??????????????????????? useInterception = true;
??????????????????????? break;
??????????????????? }
??????????????? }
??????????? }
??????????? if (useInterception)
??????????? {
??????????????? this.PreProcess(msg);
??????????? }
??????????? IConstructionCallMessage ctorInvoke = invoke as IConstructionCallMessage;
??????????? if (ctorInvoke != null)
??????????? {
??????????????? RealProxy default_proxy = RemotingServices.GetRealProxy(this._target );
??????????????? default_proxy.InitializeServerObject(ctorInvoke);
??????????????? MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();
??????????????? return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctorInvoke, tp);
??????????? }
??????????? IMethodReturnMessage returnMSG = RemotingServices.ExecuteMessage(this._target, invoke);
??????????? if (useInterception)
??????????? {
??????????????? this.PostProcess(msg, returnMSG);
??????????? }
??????????? return returnMSG;
??????? }
??????? #region implemente IInterceptor
??????? public abstract void PreProcess(IMessage requestMSG);
??????? public abstract void PostProcess(IMessage requestMSG, IMessage returnMSG);
??????? #endregion??????
??? }
}
三,代理特性的實現
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Proxies;
using LYG.Share .Interface ;
namespace LYG.Share.AOP.Proxies
{
??? [AttributeUsage(AttributeTargets.Class, AllowMultiple = false,Inherited=false)]
??? public class AspectAttribute : ProxyAttribute
??? {
??????? private Type _proxyType = null;
??????? public AspectAttribute(Type proxyType)
??????????? :base()
??????? {
??????????? _proxyType = proxyType;
??????? }
??????? public override MarshalByRefObject CreateInstance(Type serverType)
??????? {
??????????? MarshalByRefObject mobj = base.CreateInstance(serverType);
??????????? AspectProxy proxyInstance = (AspectProxy)Activator.CreateInstance(_proxyType, new object[] { serverType});
??????????? proxyInstance.InitProxyTarget(mobj);
??????????? return proxyInstance.GetTransparentProxy() as MarshalByRefObject;
??????? }
??? }
}
四,方法攔截特性的實現
using System;
using System.Collections.Generic;
using System.Text;
namespace LYG.Share.AOP.Proxies
{
??? [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
??? public class InterceptionAttribute:Attribute
??? {
??????? private bool _useInterception = false;
??????? public InterceptionAttribute(bool useInterception)
??????? {
??????????? this._useInterception = useInterception;
??????? }
??????? public bool UseInterception
??????? {
??????????? get
??????????? {
??????????????? return this._useInterception;
??????????? }
??????? }
??? }
}
五,測試用例
?public class AspectServiceProxy : AspectProxy
??? {
??????
??????? public AspectServiceProxy(Type serverType)
??????????? : base(serverType)
??????? {
??????? }
?????
??????? public override void PreProcess(IMessage requestMSG)
??????? {
????????? //對攔截方法的預處理 ?????????
??????? }
??????? public override void PostProcess(IMessage requestMSG, IMessage returnMSG)
??????? {
??????????? //對攔截方法的后處理
??????? }
??????
??? }
[Aspect(typeof(AspectServiceProxy))]
??? public class AspectServiceClass : ContextBoundObject
??? {
??????? private int _value = 0;
??????? public AspectServiceClass(int value)
??????? {
??????????? _value = value;
??????? }
??????? [Interception(true)]
??????? public int Add(int value)
??????? {
??????????? _value += value;
??????????? return _value;
??????? }????
??????
??? }
....
?????? AspectServiceClass asc=new AspectServiceClass(5);
?????? asc.Add(6);
......
總結
???? 這個AOP框架的主要優點在于當我們要為一個已經寫好的類的方法植入新的處理時,我們不需要對該類的方法實現做修改。只需要實現一個類的攔截代理(如 AspectServiceProxy),并對類加[Aspect(typeof(AspectServiceProxy))]特性,對要被攔截的方法加 [Interception(true)]特性。最重要的是被攔截的類的調用方式沒有任何的改變,AspectServiceClass asc=new AspectServiceClass(5)這樣的調用可能散布在系統的許多地方。如果被經過AOP改造后的類的調用方式發生改變那么就必須修改系統中每 一個調用改類的地方,這樣造成的代碼的變動可能不是我們所期望的,也于AOP理念的初衷是不相符合的(實現上許多的AOP框架都存在這個遺憾)。當然這個 AOP框架的缺點也是顯而易見的,首先,所有要被代理的類都必須繼承自ContextBoundObject,而事實上許多的類可能要實現其他的繼承,一 個愚蠢的辦法就是把ContextBoundObject作為系統中所有類的基類。其次,就是不能實現方法的多重攔截。
根據這個思路,可以給出一個簡單的代碼實現:
一,定義方法攔截的接口
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging;
namespace LYG.Share.Interface
{
??? public interface IInterceptor
??? {
??????? void PreProcess(IMessage requestMSG);
??????? void PostProcess(IMessage requestMSG, IMessage returnMSG);
??? }
}
二,真實代理的實現
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Services;
using LYG.Share .Interface ;
namespace LYG.Share.AOP.Proxies
{
??? public abstract class AspectProxy : RealProxy, IInterceptor
??? {
??????? private MarshalByRefObject _target = null;
??????? public AspectProxy()
??????????? : base()
??????? {
??????? }
??????? public AspectProxy(Type serverType)
??????????? : base(serverType)
??????? {
??????? }
?????????????
??????? public void InitProxyTarget(MarshalByRefObject target)
??????? {
??????????? this._target = target;
??????? }
??????? public override IMessage Invoke(IMessage msg)
??????? {
??????????? bool useInterception = false;
??????????? IMethodCallMessage invoke = (IMethodCallMessage)msg;
??????????? foreach (InterceptionAttribute attr in invoke.MethodBase.GetCustomAttributes(false))
??????????? {
??????????????? if (attr != null)
??????????????? {
??????????????????? if (attr.UseInterception)
??????????????????? {
??????????????????????? useInterception = true;
??????????????????????? break;
??????????????????? }
??????????????? }
??????????? }
??????????? if (useInterception)
??????????? {
??????????????? this.PreProcess(msg);
??????????? }
??????????? IConstructionCallMessage ctorInvoke = invoke as IConstructionCallMessage;
??????????? if (ctorInvoke != null)
??????????? {
??????????????? RealProxy default_proxy = RemotingServices.GetRealProxy(this._target );
??????????????? default_proxy.InitializeServerObject(ctorInvoke);
??????????????? MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();
??????????????? return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctorInvoke, tp);
??????????? }
??????????? IMethodReturnMessage returnMSG = RemotingServices.ExecuteMessage(this._target, invoke);
??????????? if (useInterception)
??????????? {
??????????????? this.PostProcess(msg, returnMSG);
??????????? }
??????????? return returnMSG;
??????? }
??????? #region implemente IInterceptor
??????? public abstract void PreProcess(IMessage requestMSG);
??????? public abstract void PostProcess(IMessage requestMSG, IMessage returnMSG);
??????? #endregion??????
??? }
}
三,代理特性的實現
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Proxies;
using LYG.Share .Interface ;
namespace LYG.Share.AOP.Proxies
{
??? [AttributeUsage(AttributeTargets.Class, AllowMultiple = false,Inherited=false)]
??? public class AspectAttribute : ProxyAttribute
??? {
??????? private Type _proxyType = null;
??????? public AspectAttribute(Type proxyType)
??????????? :base()
??????? {
??????????? _proxyType = proxyType;
??????? }
??????? public override MarshalByRefObject CreateInstance(Type serverType)
??????? {
??????????? MarshalByRefObject mobj = base.CreateInstance(serverType);
??????????? AspectProxy proxyInstance = (AspectProxy)Activator.CreateInstance(_proxyType, new object[] { serverType});
??????????? proxyInstance.InitProxyTarget(mobj);
??????????? return proxyInstance.GetTransparentProxy() as MarshalByRefObject;
??????? }
??? }
}
四,方法攔截特性的實現
using System;
using System.Collections.Generic;
using System.Text;
namespace LYG.Share.AOP.Proxies
{
??? [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
??? public class InterceptionAttribute:Attribute
??? {
??????? private bool _useInterception = false;
??????? public InterceptionAttribute(bool useInterception)
??????? {
??????????? this._useInterception = useInterception;
??????? }
??????? public bool UseInterception
??????? {
??????????? get
??????????? {
??????????????? return this._useInterception;
??????????? }
??????? }
??? }
}
五,測試用例
?public class AspectServiceProxy : AspectProxy
??? {
??????
??????? public AspectServiceProxy(Type serverType)
??????????? : base(serverType)
??????? {
??????? }
?????
??????? public override void PreProcess(IMessage requestMSG)
??????? {
????????? //對攔截方法的預處理 ?????????
??????? }
??????? public override void PostProcess(IMessage requestMSG, IMessage returnMSG)
??????? {
??????????? //對攔截方法的后處理
??????? }
??????
??? }
[Aspect(typeof(AspectServiceProxy))]
??? public class AspectServiceClass : ContextBoundObject
??? {
??????? private int _value = 0;
??????? public AspectServiceClass(int value)
??????? {
??????????? _value = value;
??????? }
??????? [Interception(true)]
??????? public int Add(int value)
??????? {
??????????? _value += value;
??????????? return _value;
??????? }????
??????
??? }
....
?????? AspectServiceClass asc=new AspectServiceClass(5);
?????? asc.Add(6);
......
總結
???? 這個AOP框架的主要優點在于當我們要為一個已經寫好的類的方法植入新的處理時,我們不需要對該類的方法實現做修改。只需要實現一個類的攔截代理(如 AspectServiceProxy),并對類加[Aspect(typeof(AspectServiceProxy))]特性,對要被攔截的方法加 [Interception(true)]特性。最重要的是被攔截的類的調用方式沒有任何的改變,AspectServiceClass asc=new AspectServiceClass(5)這樣的調用可能散布在系統的許多地方。如果被經過AOP改造后的類的調用方式發生改變那么就必須修改系統中每 一個調用改類的地方,這樣造成的代碼的變動可能不是我們所期望的,也于AOP理念的初衷是不相符合的(實現上許多的AOP框架都存在這個遺憾)。當然這個 AOP框架的缺點也是顯而易見的,首先,所有要被代理的類都必須繼承自ContextBoundObject,而事實上許多的類可能要實現其他的繼承,一 個愚蠢的辦法就是把ContextBoundObject作為系統中所有類的基類。其次,就是不能實現方法的多重攔截。
轉載于:https://www.cnblogs.com/Aokoo/archive/2007/06/25/794266.html
總結
以上是生活随笔為你收集整理的用代理技术实现简单的AOP框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度deepin官宣自研软件包格式“玲珑
- 下一篇: 跳伞时未成功开伞 巴西男子从2000米高