你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Linux开发
从.Net类库代码来看Asp.net运行时(5)
 
 从上面的代码可以看出,HttpApplication对象是经由HttpApplicationFactory.GetApplicationInstance(并最终调用HttpRuntime.CreateNonPublicInstance)创建的。
  HttpApplicationFactory对象会先解译目录中的Global.asax文件,接着加载虚拟目录内的Application Assembly(Global.dll),而后合并两者创建出一个Ghost Application Class,最后编译此Class后取得对象实例后返回至HttpRuntime对象,这个对象实例就是HttpApplication对象。解译与编译.asax文件的动作只发生于此虚拟目录第一次处理用户要求,或是Global.asax、Global.dll在前次执行后又做了变动时。至于HttpRuntime.CreateNonPublicInstance方法内部到底是通过什么样的代码,先后调用了Parser和Compiler,根据machine.config和web.config来生成一个HttpApplication对象,笔者未能通过自己的努力追踪到,盼高手补充。

  总之,通过machine.config及web.config档中对<httpHandlers>节点的说明,HttpApplication可以从HanlerFactory的缓存池HandlerFactoryCache中,根据当前请求的页面类型名称,获得所需的HandlerFactory。对于我们通常的aspx页面,返回的将是PageHandlerFactory(HttpApplication通过GetFactory()方法返回它),而PageHandlerFactory将接下来完成对所请求页面的Parser,并返回一个代表所请求页面的Page类:
Page page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page), context, true, true) as Page;
上面这句代码是被PageHandleFactory的GetHandle方法间接调用的(大家可以从HttpApplication.MapHttpHandler方法),调用返回的page对象是一个非常非常关键的实例(具体的方法调用过程中应当包括了对PageParser和PageBuilder的调用,望高手补充),因为它就是我们普通的aspx页面处理流程中,那个扮演着IHttpHandler的角色!也正因为此,我们在HttpRuntime.ProcessRequestInternal()方法里看到的applicationInstance.ProcessRequest(extraData)调用,实际上是调用的一个System.Web.UI.Page类型实例的ProcessRequest方法,整个执行流也因此进入了Page.ProcessRequestMain()的里面。我们平常所说的一个页面的生命周期的若干事件,您只要好好看看这个方法的实现,就都能明白了。由于这个方法估计是大家平时看的比较多的,对之也比较熟悉,本文这里就不多解释了。

四.HttpApplication的事件机制

  到上面介绍的内容为止,整个处理流程基本上就讲完了。但如果只介绍到这里,恐怕大家对HttpApplication, IHttpModule, IHttpHandler三者的关系还是不太清楚。一个请求过程的所有事件(如BeginRequest、AuthenticateRequest等)是如何被触发的?如何通过自己的自定义Module来处理这些事件?Handler的处理又是在什么位置切入的?其实,这一切都是以HttpApplication内置的事件机制为核心的,下面就让我们来一步步揭示出它的实现方式(对.net中事件机制不够熟悉的读者可以先参看笔者另一篇文章:Part I of Events in Asp.Net: Events in .Net)。这里面涉及的事件很多,我们就以BeginRequest这个事件为例来说明:
(1)首先当然是要对事件本身进行定义
public event EventHandler BeginRequest
(2)由于有不止一个事件,为了方便对所有事件的管理,给每一个事件定义了一个唯一key,用作在事件容器中查找指定事件的标志
private static readonly object EventBeginRequest;
(3)把对一个个事件触发定义为一个个“执行步骤的执行”,下面是对“执行步骤”这个接口的定义
internal interface IExecutionStep
{
// 每一个“执行步骤”的执行命令
void Execute();
// Properties
bool CompletedSynchronously { get; }
bool IsCancellable { get; }
}
(编辑:aniston)
  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089