ASP.NET的底层体系2
文章引导
引言
接着上一篇ASP.NET的底层体系1我们继续往下走
一.System.Web.HttpRuntime.ProcessRequestInternal
我们看看ProcessRequestInternal的ProcessRequest
1.为请求创建一个新的HttpContext实例
2.获取一个HttpApplication实例
3.调用HttpApplication.Init()初始化管道事件
4.Init()触发HttpApplication.ResumeProcessing(),启动ASP.NET管道处理
一个新的HttpContext对象被创建,给它传递一个封装了ISAPI ECB的ISAPIWorkerRequest。HttpContext对象还包含一个非常有用的列表集合,你可以用它存储有关特定的请求需要的数据。上下文对象创建于一个请求生命周期的开始,在请求结束时被释放。因此保存在列表集合里的数据仅仅对当前的请求有效。

二.HttpApplication
每一个请求都将被路由到一个HttpApplication对象,HttpApplication类会为你的ASP.NET程序创建一个HttpApplication对象池,它负责加载程序和给每一个请求分发HttpApplication的引用,这个HttpApplication对象池的大小可以通过machine.config的ProcessModel节点中的MaxWorkerThreads选项配置。
HttpApplication对象池尽管以比较少的项目开始启动,但是同时有多个请求需要处理时,池中的对象也会随之增加。对于你的WEB程序而言,HttpApplication是一个外部容器,它对应到Global.asax文件定义的类。基于标准的web程序,它是你实际可以看到的HTTP运行时的第一个登录点。
HttpApplication主要用于HTTP管道的事件控制器,它的接口主要由事件构成。
BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequireState
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestState
EndRequest
每一个ASP.NET WEB程序运行在各自的AppDomain里,在AppDomain里同时运行着多个HttpApplication,这些实例存放在ASP.NET管理的一个HttpApplication对象池里。
观察AppDomain ID一致保持不变,而线程和HttpAapplication的ID在请求多的时候发生改变,这是因为HttpApplication是在一个集合里运行,下一个请求可能会再次使用同一个HttpApplication实例,所以有时候HttpApplication的ID会重复,一个HttpApplication实例对象并不依赖一个特定的线程,他们仅仅是被分配给处理当前请求的线程而已。
线程由.NET的ThreadPool提供服务,默认情况下,线程模型为多线程单元(MTA),你可以通过在ASP.NET的页面的@Page指令里设置属性ASCOMPAT="true"覆盖线程单元的状态。ASPCOMPAT意味着COM组件将在一个安全的环境下运行。实际上,这些HttpApplication对象运行在同一个AppDomain里是很重要的,这就是Asp.net如何保证web.config的改变或者单独的ASP.NET页面得到验证可以贯穿整个AppDomain。改变web.config的值导致AppDomain的重新开启。这确保了所有的HttpApplication实例可以看到这些改变,这是因为当AppDomain重新加载的时候,来自ASP.NET的那些改变将会在AppDomain启动的时候重新读取,当AppDomain重新启动的时候任何静态的引用都将重新加载。
这些改变将引起Web程序重新启动,对于已经存在于处理管道的请求,将继续通过原来的管道处理,而对于那些新的请求,将被路由到新的AppDomain里,为了处理这些“挂起的请求”,在这些请求超时结束之后,ASP.NET将强制关闭AppDomain甚至这些请求该没有处理。因此在一个特定的时间上,同一个HttpApplication实例在两个AppDomain里存在是有可能的。
HttpApplication负责请求的传输,通过触发事件,通知应用程序正在发生的事情。这个是作为HttpApplication.Init()方法的一部分实现的(System.Web.HttpApplication.InitInternal和HttpApplication.ResumeSteps())。在这个方法里,创建和启动了一系列事件,包括绑定事件处理器,Global.asax里的事件处理器会自动映射到对应的事件。
通过在web.config里注册,HttpModules和HttpHandlers可以被动态的加载,并且可以添加到事件链条上,HttpModules实际就是事件处理器,可以勾住指定的HttpApplication的事件,而HttpHandlers就是一个端点,可以被调用处理“应用程序级的请求处理”。
HttpApplication本身不知晓发送给WEB程序的数据,它只是个跑腿的,它是个事件的容器,负责事件之间的通信,传递HttpContext对象。

ASP.NET管道一旦成功,HttpApplication将逐一触发事件,每一个事件将被触发,如果事件绑定了事件处理器,那么这些事件处理器将被调用,执行他们的任务。这个过程的目的是通过调用HttpHandler处理指定的请求,对于ASP.NET而言,HttpHandler是处理请求机制的核心。ASP.NET的页面和web Service都是HttpHandler的具体实现。HttpModule倾向于在分发给事件处理器之前和之后对内容进行处理
三.HttpModule
模块的本质是过滤器,在功能上类似ASP.NET请求级别的ISAPI过滤,对于每一个穿过ASP.NET的HttpApplication对象的请求,模块都允许在HttpApplication对象触发的事件处理方法里截获这些请求,这些模块以类的形式存储在外部程序集里,可以在web.config里配置。当程序启动的时候加载,通过实现指定的接口和方法,模块就可以被添加在HttpApplication的事件链上,多个HttpModules可以勾住相同的事件,事件发生的顺序跟他们在web.confg里配置顺序。
<configuration>
<sysytem.Web>
<HttpModules>
<add name="BasicAuthModule" type="HttpHandlers.BasicAuth,WebStore"/>
模块允许你查看每一个传入的web请求,基于触发的事件基础上执行操作。模块是非常有用的,它可以修改请求,输出响应的内容以及提供自定义的身份验证。另外可以在特定的程序里,针对ASP.NET的每一个请求提供响应前处理和响应后处理。
HttpModule类似ISAPI的感觉,由于他们查看进入ASP.NET程序的每一个请求,但它们的局限性仅查看映射到某一个ASP.NET程序或虚拟目录的请求和映射到ASP.NET的请求,因此你可以查看所有的ASPX页面或者任意其他自定义的已经映射到这个程序的扩展名。
实现一个HttpModule模块,它包含两个方法:Init()和Dispose(),传递的事件参数中包含一个HttpApplication对象的引用,它会给你HttpContext的访问权限。
public class BasicAuthCustomModule : IHttpModule
{ public void Init(HttpApplication application)
{
// *** Hook up any HttpApplication events
application.AuthenticateRequest +=
new EventHandler(this.OnAuthenticateRequest);
}
public void Dispose() { } public void OnAuthenticateRequest(object source,
EventArgs eventArgs)
{
HttpApplication app = (HttpApplication) source;
HttpContext Context = HttpContext.Current;
… do what you have to do… }
}
在Init()方法里,你可以勾住多个事件,因此在一个模块里,可以管理多个不同功能的操作。在HttpModules里使用HttpApplication的事件时,Response.End()和HttpApplication.CompleteRequest()方法会使ASP.NET跳过HttpApplication和模块的事件链。
四.HttpHandler
HttpModule针对每一个传入ASP.NET程序的请求触发,HTTPHandler重于处理一个指定的请求映射。HttpHandler继承IHttpHandler,这个借口有一个方法ProcessReuqest()和一个属性IsReusable。ProcessRequest()可以获取一个HttpContext。
HttpHandler的关键操作是往Response对象里写输出数据,或者更确切的说,是往Response对象的OutputStream里写,这个就是真正返回到客户端的输出数据,在底层,由ISAPIWorkerRequest负责把OutputStream发回给ISAPI的ecb.WriteClient方法,因为ecb.WriteClient才是真正执行IIS产生输出数据的。

ASP.NET的底层体系2的更多相关文章
- ASP.NET的底层体系1
文章引导 1.ASP.NET的底层体系1 2.ASP.NET的底层体系2 引言: 学习ASP.NET,要想做的更好,不了解ASP.NET是不行的.一个有理想的程序员都会像挤压海绵一样,努力的去学习和获 ...
- 窥探ASP.Net MVC底层原理 实现跨越Session的分布式TempData
1.问题的引出 我相信大家在项目中都使用过TempData,TempData是一个字典集合,一般用于两个请求之间临时缓存数据或者页面之间传递消息.也都知道TempData是用Session来实现的,既 ...
- ASP.NET MVC底层原理与框架
前言 鄙人有一毛病,喜欢钻研原理性的东西,感觉只知道怎么用还不太够,更想知道如何实现的以及为什么会这样. 暑假的时候做积分系统是第一次接触MVC,感觉MVC就是一个框架,分为Module ,view和 ...
- 【转】从底层了解ASP.NET体系结构
从底层了解ASP.NET体系结构 原文:http://blog.csdn.net/zhoufoxcn/article/details/1890158 Java体系架构的书多如牛毛,比如SSH架构什么的 ...
- (翻译)从底层了解ASP.NET体系结构 [转]
转自:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言 关于ASP.NET的底层的工作机制,最近园子 ...
- 【转】(翻译)从底层了解ASP.NET体系结构
原文地址:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言关于ASP.NET的底层的工作机制,最近园 ...
- ASP.NET底层与各个组件的初步认识与理解 (转载)
ASP.NET底层的初步认识与理解 最近在国外的网站乱走一通,发现一些比较好的文章,收集整理加于自己的理解,作为笔记形式记录下来,让以后自己有个回忆. ASP.NET是一个非常强大的构建Web应用 ...
- 从底层了解ASP.NET体系结构
导读: 前言 关于ASP.NET的底层的工作机制,最近园子里讨论的甚是火热.相信很多人都看过Rick Strahl先生的一篇经典之作:A low-level Look at the ASP.NET ...
- 学习ASP.NET Core,你必须了解无处不在的“依赖注入”
ASP.NET Core的核心是通过一个Server和若干注册的Middleware构成的管道,不论是管道自身的构建,还是Server和Middleware自身的实现,以及构建在这个管道的应用,都需要 ...
随机推荐
- 安装 Confluence6.7.1 笔记
安装 Confluence6.7.1 我是使用命令行进入mysql的mysql -uroot -p123456 创建数据库 CREATE DATABASE confluence DEFAULT CHA ...
- Android android studio常用的一些快捷键以及常用权限
android studio的常用快捷键:一.打印log:1.输入logt回车: 自动生成TAG的全局变量:private static final String TAG = "MainA ...
- lua数组和数据类型转换
一.lua数组 Lua数组大小不固定,下标是从 1开始. --数组 arr={"aaa","bbb","ccc"} --使用数值 for通 ...
- NX二次开发-UFUN将工程图转成CGM和PDF文件UF_CGM_export_cgm
文章转载自唐康林NX二次开发论坛,原文出处: http://www.nxopen.cn/thread-126-1-1.html 刚才有同学问到这个问题,如果是用NXOpen来做,直接录制一下就可以了: ...
- Linux服务器上监控网络带宽的18个常用命令nload, iftop,iptraf-ng, nethogs, vnstat. nagios,运用Ntop监控网络流量
Linux服务器上监控网络带宽的18个常用命令 本文介绍了一些可以用来监控网络使用情况的Linux命令行工具.这些工具可以监控通过网络接口传输的数据,并测量目前哪些数据所传输的速度.入站流量和出站流量 ...
- LeetCode 1103. Distribute Candies to People (分糖果 II)
题目标签:Math 题目让我们分发糖果,分的糖果从1 开始依次增加,直到分完. for loop可以计数糖果的数量,直到糖果发完.但是还是要遍历array 给people 发糖,这里要用到 index ...
- Spring随笔-bean装配-自动装配
Spring提供了三种装配方式 1.XML文件进行显式装配 2.java中进行显示装配 3.自动化装配 1.自动化装配的两种实现方式 1.组件扫描:Spring会自动发现应用上下文中创建的bean 2 ...
- hexo next主题深度优化(六),使用hexo-neat插件压缩页面,大幅度提升页面性能和响应速度。
文章目录 隆重感谢: 背景 开始 试水 成功的案例 安装插件,执行命令. hexo _config.yml文件添加 坑 跳过压缩文件的正确配置方式 压缩html时不要跳过.md文件 压缩html时不要 ...
- html清除浮动的6种方法示例
使用display:inline-block会出现的情况: 1.使块元素在一行显示2.使内嵌支持宽高3.换行被解析了4.不设置的时候宽度由内容撑开5.在IE6,7下步支持块标签 由于inline-bl ...
- IK分词器 原理分析 源码解析
IK分词器在是一款 基于词典和规则 的中文分词器.本文讲解的IK分词器是独立于elasticsearch.Lucene.solr,可以直接用在java代码中的部分.关于如何开发es分词插件,后续会有文 ...