ASP.NET从源码看实现(二):HttpApplicationFactory
IIS处理流程类:HttpApplicationFactory
//HttpApplicationFactory internal static IHttpHandler GetApplicationInstance(HttpContext context) { if (_customApplication != null) { return _customApplication; } if (context.Request.IsDebuggingRequest) { return new HttpDebugHandler(); } _theApplicationFactory.EnsureInited(); _theApplicationFactory.EnsureAppStartCalled(context); return _theApplicationFactory.GetNormalApplicationInstance(context); }
当在HttpRuntime类中调用HttpApplicationFactory.GetApplicationInstance(ctxt)方法时就进入到了HttpApplicationFactory 类库中,
首先会执行EnsureInited()方法,该方法检查HttpApplicationFactory是否被初始化,如果没有,就通过HttpApplicationFactory.Init()进行初始化。在Init()中,先获取global.asax文件的完整路径,然后调用CompileApplication()对global.asax进行编译。在CompileApplication()方法时,会反射加载global.asax中的事件(Application_Start,Application_End..)且将里面的类似于EventHandler的方法放到HttpRuntime._eventHandlerMethods中!
//HttpApplicationFactory 类 private void EnsureInited() { if (!this._inited) { lock (this) { if (!this._inited) { this.Init(); this._inited = true; } } } } private void Init() { if (_customApplication == null) { try { try { this._appFilename = GetApplicationFile(); this.CompileApplication(); } finally { this.SetupChangesMonitor(); } } catch { throw; } } } internal static string GetApplicationFile() { return Path.Combine(HttpRuntime.AppDomainAppPathInternal, "global.asax"); } private void CompileApplication() { this._theApplicationType = BuildManager.GetGlobalAsaxType(); .......this.ReflectOnApplicationType(); } private void ReflectOnApplicationType() { ArrayList list = new ArrayList(); foreach (MethodInfo info in this._theApplicationType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)) { if (this.ReflectOnMethodInfoIfItLooksLikeEventHandler(info)) { list.Add(info); } } .......... } private bool ReflectOnMethodInfoIfItLooksLikeEventHandler(MethodInfo m) { .......... Label_0089: str = m.Name; int index = str.IndexOf('_'); if ((index <= 0) || (index > (str.Length - 1))) { return false; } if (StringUtil.EqualsIgnoreCase(str, "Application_OnStart") || StringUtil.EqualsIgnoreCase(str, "Application_Start")) { this._onStartMethod = m; this._onStartParamCount = parameters.Length; } else if (StringUtil.EqualsIgnoreCase(str, "Application_OnEnd") || StringUtil.EqualsIgnoreCase(str, "Application_End")) { this._onEndMethod = m; this._onEndParamCount = parameters.Length; } else if (StringUtil.EqualsIgnoreCase(str, "Session_OnEnd") || StringUtil.EqualsIgnoreCase(str, "Session_End")) { this._sessionOnEndMethod = m; this._sessionOnEndParamCount = parameters.Length; } return true; }
_theApplicationFactory.EnsureAppStartCalled(context) 创建特定的HttpApplication实例,触发ApplicationOnStart事件,执行ASP.global_asax中的Application_Start(object sender, EventArgs e)方法。这里创建的HttpApplication实例在处理完事件后,就被回收。
private void EnsureAppStartCalled(HttpContext context) { if (!this._appOnStartCalled) { lock (this) { if (!this._appOnStartCalled) { using (new DisposableHttpContextWrapper(context)) { WebBaseEvent.RaiseSystemEvent(this, 0x3e9); this.FireApplicationOnStart(context); } this._appOnStartCalled = true; } } } }
_theApplicationFactory.GetNormalApplicationInstance(context) 该方法创建HttpApplication实例并进行初始化,调用System.Web.HttpApplication.InitInternal() 方法。创建HttpApplication实例是根据实际的_theApplicationType进行创建。如果Web目录中没有global.asax 文件,也就是说没有动态编译生成ASP.global_asax类型,那就直接实例化 HttpApplication。如果创建了ASP.global_asax类型,那就对ASP.global_asax进行实例化。
private HttpApplication GetNormalApplicationInstance(HttpContext context) { HttpApplication state = null; lock (this._freeList) { if (this._numFreeAppInstances > 0) { state = (HttpApplication) this._freeList.Pop(); this._numFreeAppInstances--; if (this._numFreeAppInstances < this._minFreeAppInstances) { this._minFreeAppInstances = this._numFreeAppInstances; } } } if (state == null) { state = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType); using (new ApplicationImpersonationContext()) { state.InitInternal(context, this._state, this._eventHandlerMethods); } } .............. return state; }

浙公网安备 33010602011771号