用代理技术实现简单的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作为系统中所有类的基类。其次,就是不能实现方法的多重拦截。

转载于:https://www.cnblogs.com/Aokoo/archive/2007/06/25/794266.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

halcon 单通道图像转成3通道_halcon图像处理基本运算

halcon图像处理基本运算图像处理最基本的操作包括颜色空间转换,各种代数运算,放射变换等。通过熟悉这些常见的操作,可以对图像有基本的认识,尤其是对刚开始接触视觉图像处理的人而言,熟悉这些操作,可以快速…

【HNOI2013】消毒

题面 题解 当只有二维时&#xff0c;就是一个二分图匹配的板子题 三维的时候就很好做了&#xff0c;暴力枚举一维的情况&#xff0c;因为\(\min(x,y,z) \sqrt{5000} < 18\)&#xff0c;于是时间复杂度有保证 代码 #include<cstdio> #include<cstring> #include…

ASP.NET MVC学前篇之Ninject的初步了解

ASP.NET MVC学前篇之Ninject的初步了解1.介绍废话几句&#xff0c;Ninject是一种轻量级的、基础.NET的一个开源IoC框架&#xff0c;在对于MVC框架的学习中会用到IoC框架的&#xff0c;因为这种IoC开源框架有很多&#xff0c;本篇的主题只有一个&#xff0c;就是让阅读过本篇幅的…

技术术语积累

目录ASCII码表ASCII打印字符ASCII非打印控制字符ASCII扩展打印字符C语言基本数据类型整型变量整型常量实数&#xff08;浮点&#xff09;类型实型&#xff08;浮点&#xff09;常量字符变量字符常量C语言中printf打印形式%2d&#xff0c;%-2d&#xff0c;%.2d&#xff0c;%02d&…

下滑加载更多js_专治:卫生间免砸砖,房顶漏水,JS堵漏王水不漏,厂家三包产品,免费成熟配方(点开看更多)...

免砸砖JS-堵漏王水不漏白色粉状&#xff0c;加水溶解后即为JS堵漏王水不漏。防水液&#xff0c;为无色透明液体&#xff0c;不燃、不爆、不腐蚀。本产品是新型多功能纳米水溶性防水剂。具有超强的渗透后微膨胀结晶功能&#xff0c;能充分填补填满物体毛细管&#xff0c;从而达到…

2010年亚运会前广州将大力推广清洁能源公交

中新社北京七月三日电 (记者 闫晓虹)当北京正在为二00八年奥运建设绿色公交的时候&#xff0c;广州公交也在为二0一0年的亚运会积极备战。广州计划在二0一0年亚运会召开之前&#xff0c;从外型设计、技术配置优化等方面进一步提高和完善LPG(液化石油气)公交车&#xff0c;并计划…

linux设置开机自启动

一.、在/etc/rc.local文件中添加自启动命令 执行命令&#xff1a; 编辑"/etc/rc.local"&#xff0c;添加你想开机运行的命令 运行程序脚本&#xff1a;然后在文件最后一行添加要执行程序的全路径。 例如&#xff0c;每次开机时要执行一个hello.sh&#xff0c;这个脚本…

JavaScript 初学者应知的 24 条最佳实践

原文&#xff1a;24 JavaScript Best Practices for Beginners &#xff08;注&#xff1a;阅读原文的时候没有注意发布日期&#xff0c;觉得不错就翻译了&#xff0c;翻译到 JSON.parse 那一节觉得有点不对路才发现是 2009 年发布的文章&#xff0c;不过还是不错的啦。另外&am…

正点原子FreeRTOS(下)

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

AJAX范例大搜罗

1&#xff0e;每天一个AJAX 该网站提供了很多非常酷的AJAX例子&#xff0c;号称是每天更新一个。 网址&#xff1a;http://www.ajaxcompilation.com/ 2&#xff0e;210个AJAX框架 一个不错的提供Ajax范例的网站&#xff0c;Ajax框架已更新至210个。 网址&#xff1a;http:…

JAVA语法——经典题目01

1.什么是JAVA虚拟机&#xff1f;为什么JAVA被称作是“平面无关的编程语言”&#xff1f; JAVA虚拟机是一个可以执行JAVA字节码的虚拟机进程。JAVA源文件被编译成能被JAVA虚拟机执行的字节码文件。 JAVA被设计成允许应用程序可以运行在任意的平台&#xff0c;而不需要程序员为每…

Solaris 下 Oracle impdp 过程中出现的问题

ORA-39002: invalid operationORA-39070: Unable to open the log file.ORA-29283: invalid file operationORA-06512: at "SYS.UTL_FILE", line 475ORA-29283: invalid file operation解决方法参考1&#xff1a;今天在使用IMPDP完成数据导入的过程中遇到“ORA-39002…

小学老师的恋爱谏言

小学一年级&#xff1a; 在女同学面前脱裤子&#xff0c;女同学说我小流氓 老师语录&#xff1a;“流氓不可怕&#xff0c;就怕流氓没文化&#xff01;所以你要好好学习&#xff0c;天天向上&#xff0c;争做“有文化&#xff0c;有知识&#xff0c;有学问&#xff0c;有才气…

蓝桥杯-微生物增殖

微生物增殖 假设有两种微生物 X 和 Y X出生后每隔3分钟分裂一次&#xff08;数目加倍&#xff09;&#xff0c;Y出生后每隔2分钟分裂一次&#xff08;数目加倍&#xff09;。 一个新出生的X&#xff0c;半分钟之后吃掉1个Y&#xff0c;并且&#xff0c;从此开始&#xff…

C socket demo

一、服务端-server.c #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #define MAXPENDING 5 #define BUFFSIZE 32 voi…

正点原子FreeRTOS(中)

更多干货推荐可以去牛客网看看&#xff0c;他们现在的IT题库内容很丰富&#xff0c;属于国内做的很好的了&#xff0c;而且是课程刷题面经求职讨论区分享&#xff0c;一站式求职学习网站&#xff0c;最最最重要的里面的资源全部免费&#xff01;&#xff01;&#xff01;点击进…

Android应用开发中的风格和主题(style,themes)

越来越多互联网企业都在Android平台上部署其客户端&#xff0c;为了提升用户体验&#xff0c;这些客户端都做得布局合理而且美观.......Android的Style设计就是提升用户体验的关键之一。Android上的Style分为了两个方面&#xff1a; Theme是针对窗体级别的&#xff0c;改变窗体…

DotText源码阅读(7) --Pingback/TrackBack

DotText源码阅读(7) --Pingback/TrackBack 博客这种服务的区别于论坛和所谓文集网站&#xff0c;很大程度上我认为是由于pingback/trackback的存在&#xff0c;使得博客这种自媒体有可以延展加入SNS的要素。所以分析博客程序&#xff0c;我们需要了解这种协议以及协议的实施细…

windows上安装mysql5.7.24

平时自己做测试的时候&#xff0c;自己安装一个mysql还是很有必要的&#xff0c;网上教程很多&#xff0c;但是自己操作过程中还是遇到了一些问题&#xff0c;这里记录一下安装过程。 一、下载mysql https://downloads.mysql.com/archives/community/ 我使用的是5.7.24的解压版…

《java设计模式》之责任链模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述责任链&#xff08;Chain of Responsibility&#xff09;模式的&#xff1a; 责任链模式是一种对象的行为模式。在责任链模式里&#xff0c;很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递&#…