zoukankan      html  css  js  c++  java
  • AOP_02 通过ContextBoundObject、ContextAttribute 上下文对象实现

     主要用于 监听对象的标记

    [AttributeUsage(AttributeTargets.Class)] public class AOPAttribute : ContextAttribute, IContributeObjectSink { // IContributeObjectSink :在远程处理调用的服务器端分配对象特定的侦听接收器, 这个地方监听到AOPAttribute标记的对象时,会执行GetObjectSink方法 public AOPAttribute() : base("Proxy") { } /// <summary> /// 获取上下文中的消息【方法】 /// </summary> /// <param name="obj"></param> /// <param name="nextSink"></param> /// <returns></returns> public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink) { return new MessageSink(nextSink); } }

    主要 用于监听继承ContextBoundObject所有对象 

    /// <summary>
        /// 任何一个需要应用上下文同步机制类的父类,
        /// 继承ContextBoundObject的子类实例称为上下文绑定对象,
        /// 而通常的类实例称为上下文灵活对象。上下文绑定的对象永远在其上下文中执行
        /// </summary>
        [AOP]  // 这里[Aop] 表示,继承AOPIntercept 所有的子类都会被监听,也可以在子类中打【aop】标签  ContextBoundObject 和ContextAttribute 配合使用
        public class AOPIntercept : ContextBoundObject
        {
            /* 通过ContextBoundObject来实现AOP,
             * 其中有大约60%的时间花在GetCustomAttribute的反射上,
             * 另外40%则是MarshalByRefObject(ContextBoundObject的基类,
             * 实际上ContextBoundObject什么事情都没做,只是单纯的继承了MarshalByRefObject)
             * 内部上下文管理上,它需要管理些啥呢?ContextBoundObject是一个上下文对象的基类
             * ,继承自它的子类将被一个特别的上下文管理起来,这个上下文包括一系列的属性集合或者规则,
             * 当进入或者离开上下文时,将强制执行规则。当使用ContextBoundObject实现AOP时,除了性能底下,
             * 其必须继承自ContextBoundObject,对于单继承的语言来讲可能带来不便。
             */
    
            // 继承 ContextBoundObject的所有子类,都会获取到上下文信息,
        }
    

      

      /// <summary>
        /// 监听消息
        /// </summary>
        public class MessageSink : IMessageSink
        {
            // 添加两个委托,用于监听执行前和执行后的过程
            public static event EventHandler<EventArgs> BeforeExcute;
    
            public static event EventHandler<EventArgs> AfterExcute;
      
            private IMessageSink _sink;
            public MessageSink(IMessageSink sink)
            {
                _sink = sink;
            }
            public IMessageSink NextSink => _sink;
    
            public IMessageCtrl AsyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg, IMessageSink replySink)
            {
                throw new NotImplementedException();
            }
            /// <summary>
            /// 以同步方式处理给定的消息 
            /// </summary>
            /// <param name="msg"></param>
            /// <returns></returns>
            public System.Runtime.Remoting.Messaging.IMessage SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg)
            {
                if (BeforeExcute != null)
                    BeforeExcute.Invoke(msg.Properties,null);
                 var message= _sink.SyncProcessMessage(msg); // 执行方法,并返回msg
                if (AfterExcute != null)
                    AfterExcute.Invoke(msg.Properties, null);
                return message;
            }
           
        }
    

      

    使用:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace 代理
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                //IMessage message = new ProxyMessage();
                //message.SendMessage("hnzheng");
    
    
    
    
    
    
                // 注册监听
                MessageSink.BeforeExcute += BeforeExcute;
                MessageSink.AfterExcute += AfterExcute;
                TestAop testAop = new TestAop();
                testAop.TestMethod("1111");
            
                Console.ReadLine();
    
    
            }
    
            public static void BeforeExcute(object sender,EventArgs e)
            {
                Console.WriteLine(nameof(BeforeExcute));
            }
            public static void AfterExcute(object sender, EventArgs e)
            {
                Console.WriteLine(nameof(AfterExcute));
            }
            static void GetString(string name)
            {
                //  GetString(name);
    
            }
        }
    
        [AOP]
        public class TestAop: AOPIntercept
        {
            public void TestMethod(string name)
            {
                Console.WriteLine(name);
            }
    
        }
     
    
    }
    

      结果:

    缺点:

    /* 通过ContextBoundObject来实现AOP,
    * 实际上ContextBoundObject什么事情都没做,只是单纯的继承了MarshalByRefObject)
    * 内部上下文管理上,ContextBoundObject是一个上下文对象的基类
    * ,继承自它的子类将被一个特别的上下文管理起来,这个上下文包括一系列的属性集合或者规则,
    * 当进入或者离开上下文时,将强制执行规则。当使用ContextBoundObject实现AOP时,除了性能底下,
    * 其必须继承自ContextBoundObject,对于单继承的语言来讲可能带来不便。
    */

  • 相关阅读:
    Centos系统修改时间临时和永久生效
    Oracle数据泵恢复用户数据实例
    Oracle修改用户密码错误次数及解锁用户
    MongoDB的启动与停止
    pip常用命令
    mysql执行拉链表操作
    Python实现人脸识别
    Mysql触发器学习
    WordCount程序
    Java学习--多态
  • 原文地址:https://www.cnblogs.com/hnzheng/p/12723170.html
Copyright © 2011-2022 走看看