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;
        }

 

posted @ 2014-11-24 17:21  飞蛾扑火  阅读(338)  评论(0)    收藏  举报