zoukankan      html  css  js  c++  java
  • 艾伟_转载:HttpApplication的认识与加深理解 狼人:

      HttpApplication对象是经由HttpApplicationFactory.GetApplicationInstance(并最终调用HttpRuntime.CreateNonPublicInstance)创建的HttpApplicationFactory它的主要任务是使用 URL 信息来查找 URL 虚拟目录和汇集的 HttpApplication 对象之间的匹配关系。

      这个工厂类的行为概括为有以下几点

      1、工厂类维护, HttpApplication 对象池并使用它们来处理应用程序的请求。池的寿命与应用程序的寿命相同。

      2、应用程序的第一个请求到达时,工厂类提取有关应用程序类型的信息(global.asax 类)、设置用于监视更改的文件、创建应用程序状态并触发 Application_OnStart 事件。工厂类从池中获取一个 HttpApplication 实例,并将要处理的请求放入实例中。如果没有可用的对象,则创建一个新的 HttpApplication 对象。要创建 HttpApplication 对象,需要先完成 global.asax 应用程序文件的编译。

      3、HttpApplication 开始处理请求,并且只能在完成这个请求后才能处理新的请求。如果收到来自同一资源的新请求,则由池中的其他对象来处理。

      4、应用程序对象允许所有注册的 HTTP 模块对请求进行预处理,并找出最适合处理请求的处理程序类型。这通过查找请求的 URL 的扩展和配置文件中的信息来完成。

      HttpApplicationFactory.GetApplicationInstance创建HttpApplication实例中有三个关键方法:

      HttpApplicationFactory._theApplicationFactory.EnsureInited()  该方法检查HttpApplicationFactory是否被初始化,如果没有,就通过HttpApplicationFactory.Init()进行初始化。在Init()中,先获取global.asax文件的完整路径,然后调用CompileApplication()对global.asax进行编译。

    HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context)  创建特定的HttpApplication实例,触发ApplicationOnStart事件,执行ASP.global_asax中的Application_Start(object sender, EventArgs e)方法。这里创建的HttpApplication实例在处理完事件后,就被回收。

      HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context) 该方法创建HttpApplication实例并进行初始化,调用System.Web.HttpApplication.InitInternal()方法。创建HttpApplication实例是根据实际的_theApplicationType进行创建。如果Web目录中没有global.asa文件,也就是说没有动态编译生成ASP.global_asax类型,那就直接实例化  HttpApplication。如果创建了ASP.global_asax类型,那就对ASP.global_asa进行实例化。

      创建HttpApplication实例之后就是调用实例的InitInternal方法。
      InitInternal方法的主要功能如下:
        1. InitModules():根据Web.Config的设置,创建相应的HttpModules。

        2. HookupEventHandlersForAppplicationAndModules:根据发生的事件,调用HttpApplication实例中相应的事件处理函数。

      3. 创建很多实现IExecutionStep接口的类的实例并添加到当前HttpApplication实例的_execSteps中,等待回调时执行。从这里我们可以看到HttpApplication是以异步的方式处理请求, 对请求的很多处理工作都放入了_execStep等待回调时执行。

         _execStep中主要的处理工作如下:
        1) 对请求的路径进行安全检查,禁止非法路径访问(ValidatePathExecutionStep)。
        2) 如果设置了UrlMappings, 进行RewritePath(UrlMappingsExecutionStep)。
        3) 执行事件处理函数,比如:BeginRequest、AuthenticateRequest等等。

      下面就是获取处理当前请求的HttpHandler,ASP.NET页面的动态编译也是在这里进行的。至此HttpApplication流程将会转到HttpHandler流程.也就是说HttpApplication 对象负责查找应该使用哪种处理程序来处理请求。HttpApplication 对象还负责检测对动态创建的、表示资源的程序集(如 .aspx 页面或 .asmx Web 服务)所进行的更改。如果检测到更改,应用程序对象将确保编译并加载所请求的资源的最新来源。HttpApplication调用ProcessRequest方法来处理用户请求,此方法会调用对应的HttpHandler来处理用户请求,HttpHandler根据用户请求的文件的扩展名处理请求,并把请求的结果,也就是HTML发送到客户浏览器.

      HttpApplication是HttpRuntime所创建的吗? 并不是,HttpRuntime只是向HttpApplicationFactory提出请求,要求返回一个HttpApplication对象。HttpApplicationFactory在接收到请求后,会先检查是否有已经存在并空闲的对象,如果有就取出一个HttpApplication对象返回给HttpRuntime,如果没有的话,则要创建一个HttpApplication对象给HttpRunTime。

      关于HttpApplication这个类的方法的实现,就不再一一解释,需要了解的,在类里面写上一个HttpApplication单词,然后右键选择“转到定义“,就可以看到里面的元数据了。

      从上面看出global类与HttpApplication十分紧密,其事上,global类是继承与System.Web.HttpApplication类。

    public class Global : System.Web.HttpApplication
        {

            
    protected void Application_Start(object sender, EventArgs e)
            {

            }
            
    //省略
        }


      假设在global类中定义变量与对象,我们在全局中是否能够取得或设置他的值呢?看下面的例子:

    Code

      在页面中设置:
      WebApp.Global.UserName = "AAAA";
      在设置前与设置后输出,你可以看到值的变化,但对变量的设置,会出现什么问题?这些就需要你在开发中去考虑了。

      如果使用过MVC框架开发的朋友就很熟其路由规则配置,其实就是设置在Global类的Application_Start事件中,如下面:

     public class MvcApplication : System.Web.HttpApplication
        {
            
    public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute(
    "{resource}.axd/{*pathInfo}");

                routes.MapRoute(
                    
    "UpcomingDinners",
                    
    "Dinners/Page/{page}",
                    
    new { controller = "Dinners", action = "Index" }
                );

                routes.MapRoute(
                    
    "Default",                                              // Route name
                    "{controller}/{action}/{id}",                           // URL with parameters
                    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
                );

            }

            
    protected void Application_Start()
            {
                RegisterRoutes(RouteTable.Routes);
            }
        }


      其实我们经常用的Application对象是HttpApplication类的一个属性,至此HttpApplication已经完成,下次转到HttpHandler流程了。

  • 相关阅读:
    perl的eval语句
    PythonWin运行出错解决办法
    python多重继承
    perl调用shell
    python正则表达式匹配中文
    perl学习2处理用户输入
    awk介绍
    perl学习3qw及数组的应用
    perl的多线程
    perl学习5子程序中自动识别参数
  • 原文地址:https://www.cnblogs.com/waw/p/2157090.html
Copyright © 2011-2022 走看看