从请求管道深入剖析HttpModule的实现机制,有图有真相

想要了解底层的原理必须对请求处理过程和页面的生命周期有点了解才方便您入门学习一下内容:

关于请求处理过程和页面的生命周期将会在接下来的日子为大家做一个深入的讲解。

HttpModule的实现机制如下:

1.请求到达ISAPIRuntime 的时候通过ProcessReqeust(下文统称pr ) 方法创建 HttpWrokRequest 对象。

2.在执行ISAPIRuntime 的pr 方法时候,方法内部的HttpRuntime 的pr 方法根据HttpWorkRequest 对象创建了上下文对象 HttpContext 。

3.在HttpRuntime 的 pr 方法内部又通过 HttpApplicationFactory 创建了一个处理应用程序的 HttpApplication 实例。

注意:HttpApplication的创建是根据Global.asax文件编译后的类型,再通过反射的方法创建的实例,由于创建实例的过程非常消耗时间和资源,这个则使用了对象池技术

4.在创建HttpApplication 实例的过程中,内部会调用InitInternal 方法,在这个方法里面 调用了HttpModule 的初始化方法,实现了事件的注册。

注意:在实现事件的注册的过程中,内部会去配置文件里面找是否有配置HttpModule模块,如果有则通过反射注册,没有则继续往下走,直到方法跳出。这个过程就是微软的插件机制的体现。

5.事件注册完之后,HttpApplication实例则开始调用自己的pr 方法开始执行页面的生命周期了。

总结:HttpModule 模块的事件注册,就是在HttpApplication 实例内部调用InitInternal 方法,这个方法里面 调用了HttpModule 的初始化方法,实现了事件的注册。

下面的代码是帮助你理解这个过程:

1、首先定义一个上下文 类    HttpContext

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5
 6 namespace HttpApplicationProcessMethodDemo
 7 {
 8     /// <summary>
 9     /// 上下文
10     /// </summary>
11     public class HttpContext
12     {
13     }
14 }

2.定义两个接口分别为: IHttpHandler 、IHttpModule

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

namespace HttpApplicationProcessMethodDemo
{
    /// <summary>
    /// 接口,这个接口主要是在application调用pr方法的时候
    /// 实现调用具体页面或一般处理程序的pr方法的。
    /// </summary>
    public interface  IHttpHandler
    {
        void ProcessRequest(HttpContext context);
    }
}

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

namespace HttpApplicationProcessMethodDemo
{
    /// <summary>
    /// 接口,这个接口主要模拟在Application 的 InitInternal方法内部实现事件的注册
    /// </summary>
    public interface IHttpModule
    {
        void Init(HttpApplication application);
    }
}

3、定义一个页面类 Page

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

namespace HttpApplicationProcessMethodDemo
{
    /// <summary>
    /// 页面类
    /// </summary>
    public class Page:IHttpHandler
    {
        /// <summary>
        /// 实现了IHttpHandler接口
        /// </summary>
        /// <param name="context">上下文</param>
        public void ProcessRequest(HttpContext context)
        {
            Console.WriteLine("页面的生命周期....");
            Console.WriteLine("..................");
            Console.WriteLine("..................");
            Console.WriteLine("..................");
            Console.WriteLine("页面的生命周期结束...");
        }
    }
}

4.定义一个应用程序类 Application

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

namespace HttpApplicationProcessMethodDemo
{
    public class HttpApplication:IHttpHandler
    {
        //初始化方法
        public void InitInternal()
        {
            //从配置文件中读取所有的注册了HttpModule的程序集,然后通过反射出实例,并调用Init方法!!!  下面的MyHttpModule假设是通过反射出来的
            IHttpModule httpModule = new MyHttpModule();

            httpModule.Init(this);

            BindEvent();

        }

        //Application 自己的事件响应方法
        private void BindEvent()
        {
            BeginRequest += new EventHandler(HttpApplication_BeginRequest);

            PostResolveRequestCache += new EventHandler(HttpApplication_PostResolveRequestCache);

            EndRequest += new EventHandler(HttpApplication_EndRequest);
        }

        void HttpApplication_EndRequest(object sender, EventArgs e)
        {
            Console.WriteLine("application自己的事件响应方法执行了--EndRequest");
        }

        void HttpApplication_PostResolveRequestCache(object sender, EventArgs e)
        {
            Console.WriteLine("application自己的事件响应方法执行了--PostResolveRequest");
        }

        void HttpApplication_BeginRequest(object sender, EventArgs e)
        {
            Console.WriteLine("application自己的事件响应方法执行了--BeginRequest");
        }

        //把此方法看成是 http 请求处理的管道
        public void ProcessRequest(HttpContext context)
        {
            //19个事件,23个步骤
            Console.WriteLine("开始请求");   

            //触发第一个事件
            BeginRequest(this, null);

            //触发第七个事件
            PostResolveRequestCache(this, null);
            Console.WriteLine("已经获取缓存");

            //第七个和第八个事件之间,创建页面对象或一般处理程序
            IHttpHandler httpHandler = new Page();
            Console.WriteLine("创建页面对象");

            //在11 和 12 个事件之间执行pr方法
            Console.WriteLine("开始执行页面的生命周期");
            httpHandler.ProcessRequest(context);

            //最后一个事件
            EndRequest(this, null);
            Console.WriteLine("结束请求");

        }

        public event EventHandler BeginRequest;
        public event EventHandler PostResolveRequestCache;
        public event EventHandler EndRequest;
    }
}

5.模拟请求管道中的执行过程

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

namespace HttpApplicationProcessMethodDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //ISAPIRuntime
            //假设根据请求创建了HttpContext上下文
            HttpContext context = new HttpContext();

            //假设从HttpApplicationFactory创建出来
            HttpApplication application = new HttpApplication();

            //把所有注册在配置文件中的HttpModule加载并执行其Init方法
            application.InitInternal();

            //调用pr方法开始执行页面的pr方法
            application.ProcessRequest(context);

            Console.ReadKey();
        }
    }
}

6.自定义一个HttpModule

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

namespace HttpApplicationProcessMethodDemo
{
    /// <summary>
    /// 自定义的HttpModule模块
    /// </summary>
    public class MyHttpModule : IHttpModule
    {
        /// <summary>
        /// 实现了IHttpModule接口
        /// </summary>
        /// <param name="application"></param>
        public void Init(HttpApplication application)
        {
            //注册事件
            application.BeginRequest += new EventHandler(application_BeginRequest);

            application.PostResolveRequestCache += new EventHandler(application_PostResolveRequestCache);

            application.EndRequest += new EventHandler(application_EndRequest);
        }

        void application_EndRequest(object sender, EventArgs e)
        {
            Console.WriteLine("HttpModule注册了EndRequest方法");
        }

        void application_PostResolveRequestCache(object sender, EventArgs e)
        {
            Console.WriteLine("HttpModule注册了PostResolveRequestCache方法");
        }

        void application_BeginRequest(object sender, EventArgs e)
        {
            Console.WriteLine("HttpModule注册了BeginRequest方法");
        }
    }
}

通过以上的步骤就实现了整个管道的执行过程和HttpModule的实现原理了。

下面是效果图:

时间: 2024-11-06 20:41:21

从请求管道深入剖析HttpModule的实现机制,有图有真相的相关文章

第五篇 基于.net搭建热插拔式web框架(拦截器---请求管道)

好了,前边我们把核心内容介绍完了,接下来要做的就是拦截用户的请求,并把请求转向沙箱内. 这里我们准备通过实现一个HttpModule类来完成请求的拦截与转发.新建一个HuberHttpModule类,并继承IHttpModule.下面我们暂时只处理Application_BeginRequest事件. 先获取request和response对象 HttpApplication application = sender as HttpApplication; HttpResponse respon

ASP.NET 管道事件与HttpModule, HttpHandler简单理解 -摘自网络

第一部分:转载自Artech  IIS与ASP.NET管道 ASP.NET管道 以IIS 6.0为例,在工作进程w3wp.exe中,利用Aspnet_ispai.dll加载.NET运行时(如果.NET运行时尚未加载).IIS 6引入了应用程序池的概念,一个工作进程对应着一个应用程序池.一个应用程序池可以承载一个或者多个Web应用,每个Web应用映射到一个IIS虚拟目录.与IIS 5.x一样,每一个Web应用运行在各自的应用程序域中. 如果HTTP.SYS接收到的HTTP请求是对该Web应用的第一

ASP.NET MVC5请求管道和生命周期

请求处理管道 请求管道是一些用于处理HTTP请求的模块组合,在ASP.NET中,请求管道有两个核心组件:IHttpModule和IHttpHandler.所有的HTTP请求都会进入IHttpHandler,有IHttpHandler进行最终的处理,而IHttpModule通过订阅HttpApplication对象中的事件,可以在IHttpHandler对HTTP请求进行处理之前对请求进行预处理或IHttpHandler对HTTP请求处理之后进行再次处理. 在IIS7之前,如IIS6或IIS5,请

ASP.NET MVC5 的请求管道和运行生命周期

https://www.jianshu.com/p/848fda7f79e0 请求处理管道 请求管道是一些用于处理HTTP请求的模块组合,在ASP.NET中,请求管道有两个核心组件:IHttpModule和IHttpHandler.所有的HTTP请求都会进入IHttpHandler,有IHttpHandler进行最终的处理,而IHttpModule通过订阅HttpApplication对象中的事件,可以在IHttpHandler对HTTP请求进行处理之前对请求进行预处理或IHttpHandler

ASP.NET MVC入门到精通——14.MVC请求管道

本系列目录:ASP.NET MVC4入门到精通系列目录汇总 ASP.NET MVC的请求管道和ASP.NET请求管道基本上一模一样,如果你对ASP.NET请求管道十分熟悉的话,你只要关注一下不同点.看懂下面两张图,你就基本上明了了,不明天的地方,用reflector工具查看MVC的源码,没其它的..NET框架的源码里面几乎涉猎了各种设计模式.这一节的内容,我也不知道怎么说,都在图里面了,看图比直接用文字说明要明了得多,比较这些东西还是比较抽象的,如果你时间充裕,建议看下MVC的源码.怎么看?就找

ASP.NET请求管道、应用程序生命周期、整体运行机制

我们知道在ASP.NET中,若要对ASP.NET应用程序进行 初始化并使它处理请求,必须执行一些处理步骤,熟悉应用程序生命周期非常重要,这样才能在适当的生命周期阶段编写代码,达到预期的效果.永远不要做只会拖 控件的.NET程序员,Never!那么你就必须懂ASP.NET应用程序生命周期,懂ASP.NET页面生命周期,懂ASP.NET 服务器控件原理.接下来,我们一起来看看 可以先看一下先导篇 [深入ASP.NET原理系列]--ASP.NET请求管道对Asp.Net WebForm和Asp.Net

如何使用请求管道中事件实现自定义方法

1.新建类xx.cs:IHttpModule,继承该接口,实现接口方法 public class ValidateSessionHttpModule : IHttpModule { public void Dispose() { throw new NotImplementedException(); } /// <summary> /// 完成请求管道中事件的注册 /// </summary> /// <param name="context">&

页面请求管道和19个标准事件

页面请求管道和19个标准事件 图片来自网络

mvc请求管道(一)

一.前言 在平常做后台开发的时候,经常会说到请求管道,很多开发者都知道这个,也能说几句,但是没办法详细的说一说,今天就来详细的说一下这个. 二.到达IIS之前 请看下面这个流程图.从用户打开浏览器到请求到达服务器,这些都是需要我们去配置就行了,这里面有一些知识点,http/https.tcp/ip.dns解析这些感兴趣的可以去了解一下. 三.请求到达IIS 同样先看流程图,Sys服务监听到有请求到达IIS,IIS会把这个请求转发给ISAPI,ISAPI即Internet Server Appli