ContextAttribute与ContextBoundObject应用开发(转)

 

ContextAttribute与ContextBoundObject应用开发

这两天因开发的需要,需要分析和构建针对ContextAttribute极其ContextBoundContext相关的拦截器的内容,所以今天一上班就开发分析ContextAttribute与ContextBoundContext之间的应用关系,在查看了相关网友的资源后开始了我的分析之路。
  首先:我建立了一个ContextAttribute的子类和一个普通的Attribute子类,分别附加在ContextBoundContext子类和普通子类上。代码如下:

using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;

namespace ContextDemo
{
    public class DemoContextAttribute : ContextAttribute
    {
        public DemoContextAttribute()
            : base("DemoContextAttribute")
        {
            Console.WriteLine("Call 'DemoContextAttribute' - 'Constructor' ");
        }

    }


    public class NonContextAttribute : Attribute
    {
        public NonContextAttribute()
        {
            Console.WriteLine("Call 'NonContextAttribute' - 'Constructor' ");
        }

    }


    [DemoContext]
    [NonContext]
    public class DemoContextBoundObject : ContextBoundObject
    {
        public DemoContextBoundObject()
        {
            Console.WriteLine("Call 'DemoContextBoundObject' - 'Constructor' ");
        }

    }


    [DemoContext]
    [NonContext]
    public class NonContextBoundObject
    {
        public NonContextBoundObject()
        {
            Console.WriteLine("Call 'NonContextBoundObject' - 'Constructor'  ");
        }

    }


    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Begin Main ");

            DemoContextBoundObject dcbo = new DemoContextBoundObject();
            NonContextBoundObject ncbo = new NonContextBoundObject();

            Console.WriteLine("End Main ");

            Console.Read();
        }

    }

}

执行的结果如下:

这里可以看出,只有继承于ContextAttribute的子类在ContextBoundObject上使用才会进行构造。其实都没有进行调用。
  然后:我将ContextAttribute之下的虚方法都进行了一次继承并且添加相应的查看信息来分析各个方法的调用顺序,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;

namespace ContextDemo  {
    public class DemoContextAttribute : ContextAttribute {
        public DemoContextAttribute()
            : base("DemoContextAttribute"{
            Console.WriteLine("Call 'DemoContextAttribute' - 'Constructor' ");
        }


        public override void Freeze(Context newContext) {
            Console.WriteLine("Call 'DemoContextAttribute' - 'Freeze' ");
        }


        public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg) {
            Console.WriteLine("Call 'DemoContextAttribute' - 'GetPropertiesForNewContext' ");
            base.GetPropertiesForNewContext(ctorMsg);
        }


        public override bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg) {
            Console.WriteLine("Call 'DemoContextAttribute' - 'IsContextOK' ");
            return false;
        }


        public override bool IsNewContextOK(Context newCtx) {
            Console.WriteLine("Call 'DemoContextAttribute' - 'IsNewContextOK' ");
            return base.IsNewContextOK(newCtx);
        }

    }


    [DemoContext]
    public class DemoContextBoundObject : ContextBoundObject {
        public DemoContextBoundObject() {
            Console.WriteLine("Call 'DemoContextBoundObject' - 'Constructor' ");
        }

    }


    class Program {
        static void Main(string[] args) {
            Console.WriteLine("Begin Main ");
            new DemoContextBoundObject();
            Console.WriteLine("End Main ");
            Console.Read();
        }

    }

}


执行的结果显示如下:

这里可能以看出在执行的过程中,先建立与ContextBoundObject相关的ContextAttribute对象。并且向ContextAttribute对象询间IsContextOK,环境怎么样还可以吗。这里我先从这个IsContextOK开始进行分析。
这里通过修改代码查看运行的结果发现IsContextOk返回的结果为False,表示对当前环境有点不满意啊,将这里的IsContextOK直接返回True会是什么情况呢。修改代码执行显示结果如下:
  public  override  bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)  {
            Console.WriteLine("Call 'DemoContextAttribute' - 'IsContextOK' ");
            return true;
        }

看来这个方式就是用来确认当前环境是否满足要求的,如果满足则不执行。这里可以查看一下这一部分的过程: 
   CRL先询问当前环境是否满足要求,如果满足则不继续执行,如果不满足则先初始化新环境的 GetPropertiesForNewContext,再将其Freeze,再询问IsNewContextOK如果没有问题则成功,如果在这里返回false,将引发一个Remoting的异常。

 

如果不能通过request对象来获取所有session,可以通过ServletContext对象来获取。以下是一种常见的实现方式: 1. 在web.xml文件中添加一个初始化参数,用于指定ServletContext的属性名称。例如: ``` <context-param> <param-name>contextAttribute</param-name> <param-value>myapp.sessions</param-value> </context-param> ``` 2. 在应用程序启动时,创建一个ServletContextListener监听器,用于在ServletContext初始化时将所有session保存到ServletContext中。例如: ``` public class SessionListener implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { ServletContext servletContext = event.getServletContext(); String attributeName = servletContext.getInitParameter("contextAttribute"); Map<String, HttpSession> sessions = new ConcurrentHashMap<String, HttpSession>(); servletContext.setAttribute(attributeName, sessions); } public void contextDestroyed(ServletContextEvent event) { ServletContext servletContext = event.getServletContext(); String attributeName = servletContext.getInitParameter("contextAttribute"); servletContext.removeAttribute(attributeName); } } ``` 3. 在应用程序中,使用ServletContext对象来获取所有session。例如: ``` ServletContext servletContext = getServletContext(); String attributeName = servletContext.getInitParameter("contextAttribute"); Map<String, HttpSession> sessions = (Map<String, HttpSession>) servletContext.getAttribute(attributeName); for (HttpSession session : sessions.values()) { //操作session } ``` 需要注意的是,这种方式需要在ServletContext初始化时将所有session保存到ServletContext中,因此需要考虑如何处理session的创建和销毁事件。另外,由于所有session都保存在内存中,可能会占用大量的系统资源,需要考虑如何优化数据结构和存储方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值