一.浏览器发出访问某ASP.NET网页的HTTP请求
假设这个请求是针对此网页所属的ASP.NET应用程序的第一次请求。当此请求到达Web服务器时,由HTTP.SYS(windows操作系统上的一个进程)负责接收,根据此请求的URL,HTTP.SYS将其传递给此ASP.NET应用程序所对应的应用程序池(什么是应用程序池?(1)),由在此应用程序池中运行的工作者进程负责处理请求。
工作者进程接收到这个请求之后,装载专用于处理ASP.NET页面的一个ISAPI扩展 aspnet_isapi.dll,并将HTTP请求传给它。
工作者进程加载完 aspnet_isapi.dll后,由aspnet_isapi.dll负责根据请求文件的后缀名判断(如果判断处理的?(2))是从IIS上返回具体物理文件还是加载ASP.NET应用程序的运行环CLR。
工作者进程工作于非托管环境(指Windows操作系统本身)之中,而.NET中的对象则工作于托管环境(指CLR)之中,aspnet_isapi.dll起到了一个沟通两者的桥梁作用,将收到的HTTP请求(由非托管环境传来)转发给相应.NET对象(处于托管环境中)处理。
二. 创建ApplicationManager对象和应用程序域
加载CLR之后,由ApplicationManager类负责创建一个应用程序域(什么是应用程序域?(3))。每个ASP.NET应用程序(什么是应用程序(4)>都运行于自己的应用程序域中,由唯一的应用程序标识符标识。 每个应用程序域都对应着一个ApplicationManager类的实例,由它来负责管理运行在域中的ASP.NET应用程序(比如启动和停止一个ASP.NET应用程序,在指定的ASP.NET应用程序中创建对象等等)。
三. 创建HostingEnvironment对象
在为ASP.NET应用程序创建应用程序域的同时,会创建一个HostingEnvironment对象,此对象提供了ASP.NET应用程序的一些管理信息(比如ASP.NET应用程序的标识,对应的虚拟目录和物理目录),并提供了一些附加的功能(比如在应用程序域中注册一个对象,模拟特定的用户等等)。
四.为每个请求创建 ASP.NET 核心对象
当应用程序域创建完成之后,一个ISAPIRuntime对象被创建,并自动调用它的ProcessRequest()方法。在此方法中,ISAPIRuntime对象根据传入的HTTP请求创建一个HttpWorkerRequest对象,此对象以面向对象的方式包装了HTTP请求的各种信息(这就是说,原始的HTTP请求信息被封装为HttpWorkerRequest对象)。然后,调用ISAPIRuntime对象的StartProcessing()方法启动整个HTTP请求处理过程(此即“HTTP管线:HTTP Pipeline”),在这个处理过程的开端,一个HttpRuntime类型的对象被创建,前面创建好的HttpWorkerRequest对象作为方法参数被传送给此HttpRuntime对象的ProcessRequest()方法。 在HttpRuntime类的ProcessRequest()方法中完成了一些非常重要的工作其中就有根据HttpWorkerRequest对象所提供的Http请求信息,创建了一个HttpContext对象。HttpContext 对象包含了在编程中非常常见的HttpResponse(返回给浏览器处理过的信息)和HttpRequest(获得Http请求信息) 两个对象。
五. 分配或者生成一个HttpApplication 对象用于处理请求
HttpRuntime类的ProcessRequest()方法除了创建HttpContext对象之外,还完成了另一个很重要的工作就是向HttpApplicationFactory类的一个实例,申请分配一个HttpApplication 对象用于管理整个HTTP请求处理管线中的各种事件。 HttpApplicationFactory对象负责管理一个HttpApplication对象池,当有HTTP请求到来时,如果池中还有可用的 HttpApplication对象,就直接分配此对象用于处理HTTP请求,否则,创建一个新的HttpApplication对象。HttpApplication 在被创建的同时会初始化一系列HttpModule对象(什么是HttpModule对象?(5)) 和一系列HttpHandler对象(什么是HttpHandler对象?(6))。
六.HttpApplication对象启动HTTP管线
HttpApplication对象负责装配出整个“HTTP请求处理管线(HTTP Pipeline)”,可以将“HTTP请求处理管线”与现代工厂中的“生产流水线”做个类比。前面步骤中创建好的HttpContext对象就是这个生产流水线要加工的“产品”,当它流经“生产流水线”的不同部分时,将被进行特定的加工和处理过程。
“HTTP请求处理管线”就是一条现代工厂中的“生产流水线”,
HttpContext对象就是这条流水线上要加工的产品。
lHttpHandler(HTTP处理程序)对象是整个“产品生产线”的核心,由它负责将产品装配成形。
lHttpModule(HTTP模块)相当于“生产线”上的辅助工人,他们对产品(HttpContext对象)进行“预处理”(为装配产品作准备)和“后处理”(为产品出厂作准备,比如贴商标)。
七.处理完成
HttpContext对象带着最后的处理结果来到了“HTTP请求处理管线”的未端,其信息被取出来,再次以aspnet_isapi.dll为桥梁传送给工作者进程。工作者进程再将HTTP请求的处理结果转给HTTP.SYS,由它负责将结果返回给浏览器。
应用程序池和应用程序域的区别:
1.一个应用程序池里可以包含多个应用程序站点。一个应用程序域只有一个应用程序。
2.应用程序池是对应用程序的非托管隔离。 应用程序域是对应用程序的托管隔离。
附件一张:
—–相关注释—–
①应用程序池:IIS6可以将单个的Web应用程序或多个站点分隔到一个独立的进程(称为应用程序池),可以包含许多应用程序域.应用程序池以独立进程的方式极大的提高了Web服务器的安全和稳定性.还可以方便的构建web garden,通过指定某个应用程序池的最大工作进程工作数量实现.
②请求的如果是静态的物理文件比如一个img ,html 等都会直接从IIS上返回原物理文件,如果是动态需要服务器处理的文件例如.aspx .asp .edmx 等则aspnet_isapi.dll负责加载asp.net应用程序运行的CLR。
③应用程序域: AppDomain是一个应用程序执行的独立环境,为执行托管代码提供隔离、卸载和安全边界. .net应用程序是由许多程序集组成的,然而不像win32程序,asp.net程序是在应用程序域中执行.应用程序域不同于win32的进程.实际上,一个进程可以有任意多的AppDomains,每个Appdomain之间是完全隔离的.运行在不同Appdomain中应用程序是不能共享信息的(全局变量,静态字段),除非用remoting.
④应用程序:asp.net将应用程序定义为所有文件、页、处理程序、模块和可执行代码的总和,该应用程序可在 Web 应用程序服务器上的给定虚拟目录(及其子目录)的范围内调用或运行.
⑤HttpModule对象:在初始化HttpApplication对象时被初始化,一个HttpApplication 可以有多个HttpModule对象,HttpModule对象的主要职责就是在不同时期把相应的事件注册到HttpApplicatioin事件当中去。比如完成身份验证,授权,操作缓存等。Asp.Net MVC UrlRouteModule路由模块就是重写了HttpModele
⑥HttpHandler对象:在初始化HttpApplication对象时被初始化,一个HttpApplication可以有多个HttpHandler对象,HttpHander负责最终处理Http请求。不同的文件有不同的HttpHander负责处理。Asp.Net MVC MvcHandle完成了最终处理。