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流程了。
随便谈识文断字,查阅大量的资料,等于收集整理加上自己的见解吧,且当成长过程中的回忆。

HttpApplication的认识与加深理解相关推荐

  1. 单片机软件模拟SPI接口—加深理解SPI总线协议

    单片机软件模拟SPI接口-加深理解SPI总线协议   SPI(Serial Peripheral Interfacer 串行外设接口)是摩托罗拉公司推出的一种同步串行通讯接口,用于微处理器臌控制器和外 ...

  2. FFT运算的加深理解——FFT的增益

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 FFT运算的加深理解--FFT的增益 前言 FFT的增益 前言 FFT的一些概念一直迷惑了好多年,包括增益.频谱泄露.加窗.补零.栅栏 ...

  3. 我的工训:加强沟通、加深理解、扩大分享!

    工训定义:工作中注重的训诫. 加强沟通:在团队协作中,永不放弃的是主动沟通的精神,在彼此都没有领会到对方的真正意图情况下,积极的做法就是进一步加强沟通,不过这时候要贴近对方的思维去探索,到底彼此的思维 ...

  4. 测试下mysql的几种连接,加深理解

    测试下mysql的几种连接,加深理解 初始表数据 table1: table2: inner join select * from table1 t inner join table2 t2 9行数据 ...

  5. FFT运算的加深理解——栅栏效应、补零、物理分辨率、计算分辨率

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 FFT运算的加深理解--栅栏效应.补零.物理分辨率.计算分辨率 栅栏效应和计算分辨率 物理分辨率 总结 栅栏效应和计算分辨率 栅栏效应 ...

  6. 原码一位乘法器设计_对原码、反码和补码的加深理解

    我们知道计算机语言可以简单概括为三类,分别是机器语言.汇编语言和高级语言.机器语言是由二进制组成的编码,由无数个0和1组成.在二进制系统中,每个0或1就是一个位,而位是数据存储的最小单位,可称之为比特 ...

  7. 第五站 使用winHex利器加深理解数据页

    这篇我来介绍一个winhex利器,这个工具网上有介绍,用途大着呢,可以用来玩数据修复,恢复删除文件等等....它能够将一个file解析成hex形式,这样你就可以对hex进行修改,然后你就可以看到修复后 ...

  8. C++——const加深理解之const在函数后

    先看下面4种情况,应该是理解const的基础,我觉得必须掌握且容易掌握 int b = 500; const int* a = &b; [1] int const *a = &b; [ ...

  9. Java线程等待唤醒机制(加深理解)

    今天看源码的时候遇到这样一个场景,某线程里面的逻辑需要等待异步处理结果返回后才能继续执行.或者说想要把一个异步的操作封装成一个同步的过程.这里就用到了线程等待唤醒机制,下面具体看一下. 等待唤醒机制示 ...

最新文章

  1. c索引超出了数组界限_Lua数组、Lua迭代器
  2. csrf防御 java_一分钟了解【CSRF攻击与防御】
  3. scratch做简单跑酷游戏_腾讯游戏学院专家:做一个多线程游戏框架可以多简单?...
  4. C++11强类型枚举,override/final
  5. 中石油训练赛 - Cafebazaar’s Chess Tournament(FFT)
  6. vue前端架构文档_Dubbo分布式架构搭建教育PC站-Vue前端:课程和登录页
  7. partition by 函数
  8. phpUnit 安装,实例和简单部署
  9. 牛客练习赛29 题解
  10. iview代码片段 去除水平menu底部横线
  11. 二进制枚举子集 CS Maxor 或运算,DP(SOS)
  12. linux系统uptime,top命令详解
  13. LINUX 下C实现线程池《转载》
  14. if函数多个条件php,excelif函数的多个条件使用方法
  15. 一个网站完整详细的SEO优化方案
  16. BZOJ 4808(马-二分图最大独立集)
  17. 一个很NB的数学绘图工具-geogebra
  18. input type=“date“
  19. 后端中dto、vo、entity的区别
  20. java 更改屏幕分辨率_Java 多屏(双屏)设置屏幕显示器分辨率方法代码(SetRes)

热门文章

  1. c语言中0级和1级是什么意思啊,C语言处理指针问题中,二级指针与一级指针的区别是什么?...
  2. java日志怎么实现_JAVA项目中怎么实现一个通用日志记录功能
  3. 计网期末复习 - 子网划分
  4. 计算机word数字逆序输出,如何让word中的内容倒序排列
  5. __name__ == '__main__'的用法
  6. Android--调用系统照相机拍照与摄像
  7. DFS-20190206
  8. Java 持久化操作之 --io流与序列化
  9. Hadoop伪分布安装详解(四)
  10. python之模块之shutil模块