• IIS5与IIS6 应用程序生命周期和页生命周期


    在写这篇博客之前,知好多前辈已经写过,自己班门弄斧,主要是加深自己对细节的理解,另一方面希望对浏览此篇文章的读者一个新的认识。注定是一长篇。肯定有新的认识,图示都是原创。

    此篇所有牵涉的细节,我会一一列出,估计持续更新数日。

    当从浏览器发送到服务器一个请求,整个流程与细节的把握。IIS5和IIS6的有些许的不同。

    全面理解,把握细节

    一,请求到达IIS再到Framework。若看以下的讲解,需要了解:

    1,IIS5和IIS6都具备inetinfo.exe进程。

    2, inetinfo.exe(任务管理器看到)的作用:包括许多由IIS提供的服务(HTTP、FTP、SMTP等)。Inetinfo.exe接收来自TCP/IP子系统的请求,并将这些请求送往各自的服务,      这些服务又解释请求,执行请求,并把结果返回给客户机。因为所有这些服务都在同一个进程  (inetinfo.exe)  中运行,所以它们能够共享高速缓存的数据,如文件句柄、      帐户信息和日志文件数据。

    3,Name Pipes命名管道是一种协议,相当于TCP/IP中的Socket协议,两者有很大的相似之处,用到局域网和广域网的各自优点。

         详情请参照:http://msdn.microsoft.com/zh-cn/library/ms187892.aspx

    4,inetinfo.exe和aspnet_isapi.dll的关系,这里之处为”调用“是否有不妥之处。也就是了解.exe文件和.dll文件的之间的关系,此点自己查阅相关资料。

    5,注册表:在这里的主要作用为文件的关联。详情自己查阅相关资料。

    6,Work Process工作者进程在IIS5和IIS6分别叫做w3wp.exe和aspnet_wp.exe。两者指得都是工作者进程,只是名字不同。

    7,IIS(非托管)和FrameWork(托管)之间的通信:IIS是非托管程序,而FrameWork上是托管程序,两者通过指针ecb将Request传递资源包。

    8,托管和非托管代码代码。请参考:http://www.cnblogs.com/Holmes-Jin/archive/2012/03/14/2396411.html

    9,http.sys在(C:WindowsSystem32drivers)中,内核模式与用户模式,属于操作系统的知识,这里不做深入研究。

    一,IIS5inetinfo.exe接受来自浏览器的请求,然后调用”aspnet_isapi.dll“,aspnet_isapi.dll"遵照"”命名管道协议Named Pipes“通过ecb指针(非托管的资源包)和Work Process(w3wp.exe)进行传输,此时aspnet_isapi.dll与w3wp.exe属于不同的进程,传输效率不是最优的,在iis6中优化了这一点。

    二,IIS6是服务器的网卡驱动内核模块C:WindowsSystem32drivershttp.sys监听到,然后会查询注册表Regitry此请求和那个应用程序关联(注册表的用途之一处理。交予W3SVC服务属于svchost.exe进程中的一个服务,能在任务管理器“服务“中看到)然后查看inetinfo.exe交予aspnet_isapi.dll,此时的aspnet_isapi.dll被划进Worker Process工作者进程中(aspnet_wp.exe),交予FrameWork处理。因为aspnet_wp.exe与FrameWork属于同一工作者进程,传输效率大大优于IIS5。IIS6,它是完全为ASP.NET做过优化的。

    是的,我也做个图。

    二,请求到达进入framework后所做的处理。

    对所请求的文件的文件扩展名进行检查,确定应由哪个 ISAPI 扩展处理该请求,然后将该请求传递给合适的 ISAPI 扩展。ASP.NET 处理已映射到其上的文件扩展名,如 .aspx、.ascx、.ashx 和 .asmx

     1,先创建“appdomain”,应用程序域。隔离作用。有关应用程序域的作用:请参考http://www.cnblogs.com/leslies2/archive/2012/03/06/2379235.html

    由System.Web.Hosting.ApplicationManager类,此类有公开的方法和未公开的方法,大多和客户端和服务端的应用程序域有关系。详情:http://msdn.microsoft.com/zh-cn/system.web.hosting.applicationmanager.aspx

     2,创建“hostingenvironment”,宿主环境。

    由System.Web.Hosting.HostingEnviroment类实例化一个对象创建。详情参考:http://msdn.microsoft.com/zh-cn/library/vstudio/System.Web.Hosting.HostingEnvironment(v=vs.100).aspx

    3,创建核心对象,ISAPIRuntimeHttpRuntime,HttpWorkRequest、HttpContext、HttpRequest、HttpResponse和和HttpApplicationFactory、HttpApplication。实现IHttpHandler

    此过程最为复杂,自己理解,

    第一,由aspnet_isapi.dll调用System.Web.Hosting.ISAPIRuntime类中的ProcessRequest方法。此类有2个重要作用。读者可以用反编译工具查询这个类。

    作用:1,接受IntPtr类型的指针变量ecb创建System.Web.HttpWorkRequest类wr对象。大多数情况下,代码不会直接处理 HttpWorkerRequest,这是因为请求和响应数据是通过HttpRequest和 HttpResponse 类公开的。

    作用:2,调用HttpRuntime类的public static void ProcessRequest(HttpWorkerRequest wr)调用ProcessRequestNoDemand(wr);方法继续调用ProcessRequestNow(wr);方法继续调用theRuntime.ProcessRequestInternal(wr);方法创建HttpContext 有context = new HttpContext(wr, false);读者也可以用反编译工具查询这个类。

    第二,创建HttpApplicationFactory对象,将context创建并传值到Application对象。在创建之前HttpApplicationFactory会到HttpApplication池中查看,有没有空闲的。若有直接用。没有的时候才创建新的HttpApplication。读者也可以用反编译工具查询这个类。

    第三,HttpRuntime类创建Context的时候同样具有另外一个作用,调用HttpApplicationFactory就是创建Appplication对象,IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);继续调用theApplicationFactory.GetNormalApplicationInstance(context);

    有关HttpApplication。是作用整个程序运行期间(用于数据共享)。

    HttpRquerst(URL传来的Querystring和提交的表单form数据)。

    HttpResponse(有一个TextWriter对象,存储想浏览器发送的数据。)

    有关TextWriter和Render方法,以下简介:有关到页面生命周期。下面会有讲述。

    1,

    System.IO.TextWriter有个子类叫做System.Web.UI.HtmlTextWriter  用reflector可以看到public class HtmlTextWriter : TextWriter

     根据MSDN的描述,HtmlTextWriter类用于将标记字符和文本写入到ASP.NET服务器控件输出流。此类提供了ASP.NET服务器控件在向客户端呈现标记时所使用的格式设置功能。

    HtmlTextWriter是一个储存html代码的类。示例:http://blog.itpub.net/14466241/viewspace-573265/

    2,

    ①但是上面的向“客户端呈现”是另一个类的功能,Render方法。此方法有好多类都具有,“呈现“。多为虚方法,让其自定义子类实现多态。比如ControlAdapter用于改写控件的html代码的一个类。

    在处理的这个阶段,Page 对象会在每个控件上调用此方法。所有 ASP.NET Web 服务器控件都有一个用于写出发送给浏览器的控件标记的 Render 方法。

    创建自定义控件的时候,通常要覆盖此方法以输出控件的标记。不过,如果自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不需要覆盖 Render方法。示例:http://www.cnblogs.com/tonyqus/archive/2005/02/15/104576.html

    public abstract class ControlAdapter
    {
    protected internal virtual void Render(HtmlTextWriter writer);
    
    }
    ②当然render方法也存在System.Web.UI.Control中,也是虚方法。
    protected internal virtual void Render(HtmlTextWriter writer)
    {
        this.RenderChildren(writer);
    }
    

    public class HttpApplication : IComponentIDisposableIHttpAsyncHandlerIHttpHandlerIRequestCompletedNotifierISyncContext



    **IhttpHangdler 里的pr方法,被Web.UI.Page与HttpApplication继承。就是将“上下文”返回到浏览器。

    **IhttpModule:当一个过滤器Filter(自定义一个类),1,继承此接口2,实现此接口中的init(Application context)方法 ,3并在config文件配置
    Global文件就是继承了Application类,就是一个过滤器,简化了自定义过滤器的步骤(省去config配置等麻烦),工作中就用这种形式,想做其他的事件 只需Application_事件名字就OK.
    Application 本身具有一些事件 start end 等。一旦程序运行,就是种存在,共享。

    public class Global : System.Web.HttpApplication
    {

    protected void Application_Start(object sender, EventArgs e)
    {

    }

    protected void Session_Start(object sender, EventArgs e)
    {

    }

    protected void Application_BeginRequest(object sender, EventArgs e)
    {

    }

    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {

    }

    protected void Application_Error(object sender, EventArgs e)
    {

    }

    protected void Session_End(object sender, EventArgs e)
    {

    }

    protected void Application_End(object sender, EventArgs e)
    {

    }


    了解这两个接口:同样意义很大。
    ①public interface IHttpHandler
    {
      // Methods
      void ProcessRequest(HttpContext context);
      // Properties
      bool IsReusable { get; }
    }
    ②public interface IHttpModule
    {
        // Methods
        void Dispose();
        void Init(HttpApplication context);
    }
    
     
    4,由HttpApplication管道处理请求。

    下面是请求管道中的19个事件.

    (1)BeginRequest: 开始处理请求

    (2)AuthenticateRequest授权验证请求,获取用户授权信息

    (3):PostAuthenticateRequest获取成功

    (4):AunthorizeRequest 授权,一般来检查用户是否获得权限

    (5):PostAuthorizeRequest:获得授权

    (6):ResolveRequestCache:获取页面缓存结果

    (7):PostResolveRequestCache 已获取缓存 

    (8):PostMapRequestHandler 创建页面对象:aspx创建了页面对象,控件树。ashx创建最终处理当前http请求的 Handler 实例: 第一从HttpContext中获取当前的PR Handler ,Create
    获取当前的上下文(HttpContext)已经映射了PrHandler没?是:结束。空的话:创建PrHandler对象实例

    (9):PostAcquireRequestState 获取Session

    (10)PostAcquireRequestState 获得Session

    (11)PreRequestHandlerExecute:准备执行页面对象
    **中间调用页面对象继承Page类(继承IhttpHangdler类 )的子类页面对象的ProcessRequest方法,(在Application里转换成接口IhttpHandler 的通过反射被请求页面对象的ProcessRequest 方法).

    (12)PostRequestHandlerExecute 执行完页面对象了

    (13)ReleaseRequestState 释放请求状态

    (14)PostReleaseRequestState 已释放请求状态

    (15)UpdateRequestCache 更新缓存

    (16)PostUpdateRequestCache 已更新缓存

    (17)LogRequest 日志记录

    (18)PostLogRequest 已完成日志

    (19)EndRequest 完成

    对的我需要来个图。

    4,在Application的第8个事件创建处理对象的时候,这里就以aspx为例子。执行页面的生命周期。流程是这样的。

    首先随便vs建一个应用程序,添加一个web窗体,后置代码反射出其对应的DLL,然后用Reflector反编译查看此页面的执行的周期。

    得到的

    打开此路径,记得一定是红线标出的路径!!!!而不是dll之前的那个,如果直接将这个dll弄到reflector里面,会查看到你自己写的后置代码,并不能看到页面执行的东西。
    移动到reflector里面的结果。

     此页面,先建立控件树。然后执行页面的PR方法,进一步调用。

    主要执行的ProcessRequestMain方法。开始执行里面流程。这里面的一定要仔细看。大家自己反编译。大家查看这个类再与MS给的生命周期对比。多理解几遍就很自然清楚。
    http://msdn.microsoft.com/zh-cn/library/ms178472(VS.80).aspx页面生命周期概述。
     
    最后推荐一个精简的博客。图示

    
    

    此图,是别人所做,我找不到这人的博客了。只有图被摘下。在此特别注释。

  • 相关阅读:
    Lodop客户端本地角色注册号常见误区
    Spring中加载xml配置文件的六种方式
    源程序出现各种奇怪的符号P
    MyEclipse项目中的java文件的图标变成空心的问题
    servlet中的相对路径和绝对路径 及/, ./, ../的区别
    Thread 与 Runnable
    Class.forName()用法详解
    chain.doFilter(request,response)含义
    jsp简单标签开发(一)
    createStatement()的用法
  • 原文地址:https://www.cnblogs.com/leee/p/4169167.html
Copyright © 2020-2023  润新知