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类。
{
protected void Application_Start(object sender, EventArgs e)
{
}
//省略
}
假设在global类中定义变量与对象,我们在全局中是否能够取得或设置他的值呢?看下面的例子:
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 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的认识与加深理解相关推荐
- 单片机软件模拟SPI接口—加深理解SPI总线协议
单片机软件模拟SPI接口-加深理解SPI总线协议 SPI(Serial Peripheral Interfacer 串行外设接口)是摩托罗拉公司推出的一种同步串行通讯接口,用于微处理器臌控制器和外 ...
- FFT运算的加深理解——FFT的增益
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 FFT运算的加深理解--FFT的增益 前言 FFT的增益 前言 FFT的一些概念一直迷惑了好多年,包括增益.频谱泄露.加窗.补零.栅栏 ...
- 我的工训:加强沟通、加深理解、扩大分享!
工训定义:工作中注重的训诫. 加强沟通:在团队协作中,永不放弃的是主动沟通的精神,在彼此都没有领会到对方的真正意图情况下,积极的做法就是进一步加强沟通,不过这时候要贴近对方的思维去探索,到底彼此的思维 ...
- 测试下mysql的几种连接,加深理解
测试下mysql的几种连接,加深理解 初始表数据 table1: table2: inner join select * from table1 t inner join table2 t2 9行数据 ...
- FFT运算的加深理解——栅栏效应、补零、物理分辨率、计算分辨率
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 FFT运算的加深理解--栅栏效应.补零.物理分辨率.计算分辨率 栅栏效应和计算分辨率 物理分辨率 总结 栅栏效应和计算分辨率 栅栏效应 ...
- 原码一位乘法器设计_对原码、反码和补码的加深理解
我们知道计算机语言可以简单概括为三类,分别是机器语言.汇编语言和高级语言.机器语言是由二进制组成的编码,由无数个0和1组成.在二进制系统中,每个0或1就是一个位,而位是数据存储的最小单位,可称之为比特 ...
- 第五站 使用winHex利器加深理解数据页
这篇我来介绍一个winhex利器,这个工具网上有介绍,用途大着呢,可以用来玩数据修复,恢复删除文件等等....它能够将一个file解析成hex形式,这样你就可以对hex进行修改,然后你就可以看到修复后 ...
- C++——const加深理解之const在函数后
先看下面4种情况,应该是理解const的基础,我觉得必须掌握且容易掌握 int b = 500; const int* a = &b; [1] int const *a = &b; [ ...
- Java线程等待唤醒机制(加深理解)
今天看源码的时候遇到这样一个场景,某线程里面的逻辑需要等待异步处理结果返回后才能继续执行.或者说想要把一个异步的操作封装成一个同步的过程.这里就用到了线程等待唤醒机制,下面具体看一下. 等待唤醒机制示 ...
最新文章
- c索引超出了数组界限_Lua数组、Lua迭代器
- csrf防御 java_一分钟了解【CSRF攻击与防御】
- scratch做简单跑酷游戏_腾讯游戏学院专家:做一个多线程游戏框架可以多简单?...
- C++11强类型枚举,override/final
- 中石油训练赛 - Cafebazaar’s Chess Tournament(FFT)
- vue前端架构文档_Dubbo分布式架构搭建教育PC站-Vue前端:课程和登录页
- partition by 函数
- phpUnit 安装,实例和简单部署
- 牛客练习赛29 题解
- iview代码片段 去除水平menu底部横线
- 二进制枚举子集 CS Maxor 或运算,DP(SOS)
- linux系统uptime,top命令详解
- LINUX 下C实现线程池《转载》
- if函数多个条件php,excelif函数的多个条件使用方法
- 一个网站完整详细的SEO优化方案
- BZOJ 4808(马-二分图最大独立集)
- 一个很NB的数学绘图工具-geogebra
- input type=“date“
- 后端中dto、vo、entity的区别
- java 更改屏幕分辨率_Java 多屏(双屏)设置屏幕显示器分辨率方法代码(SetRes)
热门文章
- c语言中0级和1级是什么意思啊,C语言处理指针问题中,二级指针与一级指针的区别是什么?...
- java日志怎么实现_JAVA项目中怎么实现一个通用日志记录功能
- 计网期末复习 - 子网划分
- 计算机word数字逆序输出,如何让word中的内容倒序排列
- __name__ == '__main__'的用法
- Android--调用系统照相机拍照与摄像
- DFS-20190206
- Java 持久化操作之 --io流与序列化
- Hadoop伪分布安装详解(四)
- python之模块之shutil模块