转载:http://www.cnblogs.com/wupeiqi/archive/2013/03/10/2952214.html
前天去面试,让我说下生命周期,本来之前就了解过,但是没说出来,被深深的鄙视了;今天弄了一上午,现在发到这分享一下,有什么错误请各位大牛们指出~~
页面发送请求原理
浏览器将请求封装成Http请求报文发送到服务器;
服务器端HTTP.SYS内核驱动模块来接收,这个模块监听着80
端口.
它首先去访问注册表确定请求交给谁去处理.
将请求交给了IIS IIS中分为了两块
1.
w3svc服务 .它是寄宿在svchost.exe进程里.主要负责将请求分发给具体的扩展程序. 具体分发给谁呢?
2.配置是在InetInfo这个进程里面.
这是iis的核心进程,这里放着IIS的元数据.
在这里.访问IIS核心进程,分析当前后缀的请求是静态还是动态.要交给哪个扩展来处理(.aspx;.ashx
动态的交给aspnet_isapi.dll处理).如果是静态的直接返回到HTTP.SYS 在浏览器中显示,如果是动态
,交给一个aspnet_isapi.dll这个扩展处理 在IIS5中,
是aspnet_wp.exe;在IIS6中和7中,是w3wp.exe
每一个网站都跑在一个单独的工作进程里面,网站间是通过进程进行隔离的.(不同的网站跑在不同的进程里面,这个称为应用程序池技术)
而在IIS5中,只是有一个进程,它是通过应用程序域来隔离每个进程之间的关联;
如果是动态页面的话.w3svc服务将请求又交给了aspnet_isapi.dll这个扩展. 这个扩展负责启动aspnet runtime,负责创建aspnet运行环境.还负责将请求交给ISAPIRuntime的PR方法,也就是非托管和托管程序的入口
在ISAPIRuntime,这就可以看到之后的源代码了
1.ISAPIRuntime对象
它调用了它的一个.ProcessRequest(ecb)方法;
ecb是一个操作系统的句柄,指向了当前请求的内存空间,可以通过此句柄来拿到当前请求的报文;通过ecb句柄,创建了一个HttpWorkRequest对象.此对象就是对Http请求报文做了一些简单的封装.也就是请求的报文头,报文体而已;
再一次的将请求给下面分发
分发给了HttpRuntime这个对象,
又调用了RrocessRequest(wr)方法;将ecb句柄创建的WorkRequest对象传进去.根据这个对象封装了一个HttpContext(请求上下文)
HttpContext中包括了HttpRequest(封装http请求),还有一个是
HttpResponse(封装了Http的响应)
并且HttpRuntime还根据HttpApplicationFactory工厂
获取一个HttpAplication对象
在这个工厂中,获取实例的时候,先去Applition池里去面去查看有没有空闲的HttpApplication对象.如果有直接返回,如果没有那么就先编译global文件生成一个HttpAppliction的派生类,然后根据这个派生类反射创建一个HttpAppliction类型实例并返回.
这个HttpAplication对象,调用了ProcessRequest(HttpContext
context)执行19个管道事件,流动着的就是HttpContext上下文 context 这需要走23个步骤
在第8个事件中,根据请求的地址,创建一般处理程序或者是aspx页面类型,并转成IHttpHandler接口对象;
在第9个事件中,会接收浏览器发送过来的SessionId,并且根据此值到服务器的Session池中找到对应的session对象,先尝试将页面类对象转换成IRequiresSessionState接口对象,如果转换不成功,刚不加载Session对象,如果转换成功则
将它赋值给页面对象的Session属性;(Page.HttpContext.HttpSessionState)
(页面生命周期)
第一步:创建控件树
在11到12个事件中.执行页面类(一般处理程序)的ProcessRequest方法
;
过程看下图