Http Pipeline详细分析1

 继续上一章节的内容,通过HttpApplicationFactory的GetApplicationInstance静态方法获取实例,然后执行该实例的BeginProcessRequest方法进行执行余下的Http Pipeline 操作,代码如下:

// Get application instance
IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context);

那GetApplicationInstance这个方法究竟做了啥呢?难道只是new一个新对象出来?感觉应该不像,那我们就来看看HttpApplicationFactory类的GetApplicationInstance静态方法源码:

internal static IHttpHandler GetA
风景
pplicationInstance(HttpContext context) {   
if (_customApplication != null) return _customApplication; // Check to see if it's a debug auto-attach request if (context.Request.IsDebuggingRequest) return new HttpDebugHandler(); _theApplicationFactory.EnsureInited(); _theApplicationFactory.EnsureAppStartCalled(context); return _theApplicationFactory.GetNormalApplicationInstance(context); }

里面有3行代码我已经标记为粗体了,在解释每行代码的具体作用之前,先看看_theApplicationFactory对象实例从哪里来,通过查看该字段的声明代码可以看到它是单例的实现。

// the only instance of application factory  
private static HttpApplicationFactory _theApplicationFactory = new HttpApplicationFactory();

第一行粗体代码是执行,该实例的EnsureInited方法,这个方法会通过lock的方式调用Init方法(好处自然不用多说了吧),代码如下:

private void EnsureInited() {  
    if (!_inited) {  
        lock (this) {   
            if (!_inited) {  
                Init();   
                _inited = true;   
            }  
        }   
    }  
}

通过查找 Init方法的代码以及其中2行如下代码里的细节,我们可以得知,这2行代码主要是从global.asax获取内容,然后进行编译。

_appFilename = GetApplicationFile();
CompileApplication();

所以,HttpApplicationFactory._theApplicationFactory.EnsureInited()  的方法首先检查HttpApplicationFactory是否被初始化,如果没有,就通过HttpApplicationFactory.Init()进行初始化。在Init()中,先获取global.asax文件的完整路径,然后调用CompileApplication()对global.asax进行编译。

第2行粗体的EnsureAppStartCalled方法,最终会调用如下的私有方法FireApplicationOnStart,代码如下:

private void FireApplicationOnStart(HttpContext context) {   
    if (_onStartMethod != null) {   
        HttpApplication app = GetSpecialApplicationInstance();  
       
        app.ProcessSpecialRequest(  
                                    context,  
                                    _onStartMethod,  
                                    _onStartParamCount,   
                                    this,  
                                    EventArgs.Empty,   
                                    null);   
      
        RecycleSpecialApplicationInstance(app);   
    }  
}

通过代码我们能够得知 HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context)   创建特定的HttpApplication实例,触发ApplicationOnStart事件,执行ASP.global_asax中的 Application_Start(object sender, EventArgs e)方法。然后在处理完事件以后就立即被回收掉,因为系统初始化只需要一次,但是其中的GetSpecialApplicationInstance里会对IIS7做一些特殊的事情,我们后面的章节会讲到。

第3行的粗体代码是我们这里要说的重点,它方法里的代码如下:

private HttpApplication GetNormalApplicationInstance(HttpContext context) {  
    HttpApplication app = null;   
      
    lock (_freeList) {  
        if (_numFreeAppInstances > 0) {  
            app = (HttpApplication)_freeList.Pop();   
            _numFreeAppInstances--;  
       
            if (_numFreeAppInstances < _minFreeAppInstances) {   
                _minFreeAppInstances = _numFreeAppInstances;  
            }   
        }  
    }  
      
    if (app == null) {   
        // If ran out of instances, create a new one  
        app = (HttpApplication)HttpRuntime.CreateNonPublicInstance(_theApplicationType);   
       
        using (new ApplicationImpersonationContext()) {  
            app.InitInternal(context, _state, _eventHandlerMethods);   
        }  
    }  
      
    return app;   
}

本栏目更多精彩内容:.




转载请注明:http://www.shhjfk.com/xxzl/xxzl/18.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了