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

public class Global : System.Web.HttpApplication

    {

        public static string UserName = "James Lee";

        protected void Application_Start(object sender, EventArgs e)

        {

}

        //省略

    }

  在页面中设置:
  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流程了。

时间: 2024-08-04 01:29:33

HttpApplication的认识与加深理解的相关文章

正则表达式字符类加深理解

正则表达式字符类加深理解: 一.基本概念: 字符类相对来说是比较简单的,但是也有可能由于理解不够深入或者大意造成一些误区,下面再来做一下介绍. 字符类[]能够匹配包含在中括号中的一系列字符中的任意一个,但是匹配的结果只能够是其中的一个而不是多个,例如: var str="abcd"; var reg=/[abcd]/; console.log(str.match(reg)); 以上正则表达式只能够匹配字符"a". 二.使用连字符"-": 字符类可

用实验方法加深理解Oracle的外连接(left/right/full)和内连接(inner)

总是对Oracle的左连接.右连接以及(+)对应的外连接类型糊涂,通过实验加深对连接类型语法的理解.外连接分为三种: 1. 左外连接,对应SQL关键字:LEFT (OUTER) JOIN 2. 右外连接,对应SQL关键字:RIGHT (OUTER) JOIN 3. 全外连接,对应SQL关键字:FULL (OUTER) JOIN 左右外连接都是以一张表为基表,在显示基表所有记录外,加上另外一张表中匹配的记录.如果基表的数据在另一张表中没有记录,那么相关联的结果集行中显示为空值. 精确点说,引用MO

HttpRuntime的认识与加深理解

下面最先介绍HttpRuntime的Web.config里的配置 <httpRuntime    executionTimeout = "number"     maxRequestLength = "number"     requestLengthDiskThreshold = "number"     useFullyQualifiedRedirectUrl = "[True|False]"     minFree

Sql Server之旅——第六站 使用winHex利器加深理解数据页

        这篇我来介绍一个winhex利器,这个工具网上有介绍,用途大着呢,可以用来玩数据修复,恢复删除文件等等....它能够将一个file解析成 hex形式,这样你就可以对hex进行修改,然后你就可以看到修复后的结果,为什么要在sqlserver系列中说这个呢???很简单呀,sqlserver的DB本 质上也是一个mdf文件,对吧,既然是文件,我就可以利用winhex对它进行随意的修改,然后你也知道sqlserver的数据都是以数据页的形式封装的, 那我就可以修改它的数据页,对不对,这样

艾伟_转载:HttpRuntime的认识与加深理解

下面最先介绍HttpRuntime的Web.config里的配置 <httpRuntime   executionTimeout = "number"    maxRequestLength = "number"    requestLengthDiskThreshold = "number"    useFullyQualifiedRedirectUrl = "[True|False]"    minFreeThrea

Linux Debugging(七): 使用反汇编理解动态库函数调用方式GOT/PLT

     本文主要讲解动态库函数的地址是如何在运行时被定位的.首先介绍一下PIC和Relocatable的动态库的区别.然后讲解一下GOT和PLT的理论知识.GOT是Global Offset Table,是保存库函数地址的区域.程序运行时,库函数的地址会设置到GOT中.由于动态库的函数是在使用时才被加载,因此刚开始GOT表是空的.地址的设置就涉及到了PLT,Procedure Linkage Table,它包含了一些代码以调用库函数,它可以被理解成一系列的小函数,这些小函数的数量其实就是库函数

站长对用户体验的理解要与时俱进

怎样才能让网站在百度那里获得一个好的排名?这个问题如果用最简洁的方式来回答,那就是做好网站的用户体验.用户体验这个概念主要还是在近些年火了起来,也是因为百度格外的重视这方面.那么,既然要有用户体验,什么样的用户体验才是被百度看重而且承认的? 我想,考虑过这个问题的站长恐怕是少之又少吧,大家虽然都说要重视用户体验,可是更多的时间还是花在了网站内容与外链的建设上.用户感觉好,用户喜欢的,那就是好的用户体验--这话说得太过于笼统,而且也无法准确的说明随着百度的变更,对用户体验的定义带来的一些改变.下面

理解 Python 中s可变参数的 *args 和 **kwargs

使用默认参数的可变参数 Python是支持可变参数的,最简单的方法莫过于使用默认参数,例如: def test_defargs(one, two = 2): print 'Required argument: ', one print 'Optional argument: ', two test_defargs(1) # result: # Required argument: 1 # Optional argument: 2 test_defargs(1, 3) # result: # Re

Javascript之旅——第十站:为什么都说闭包难理解呢?

研究过js的朋友大多会说,理解了js的原型和闭包就可以了,然后又说这些都是js的高级内容,然后就又扯到了各种神马的作用域...然后不少 人就会被忽悠的云里雾里...下面我也试着来说说闭包,看我说的这个是否浅显易懂...   一:闭包含义 闭包是个专业词汇,这样才能显得在js中是高大上的货色,官方定义我这里就不敢修改它,定义如下:就是有权访问另一个函数作用域的变量的函数.   二:一个简单的场景 上面的定义大概也能看得懂,但是不知道为什么不把"另一个函数" 改成 "包含函数&q