看到这个题目你一定会很吃惊其实最初我只是想把这篇blog命名为《ASPNET掀起你的盖头来》但后来还是抑制不住心中的兴奋之情换成了这个霸气十足的题目是的我真的很兴奋毕竟一个礼拜之前我对这些东西知之甚少我整整用了一个礼拜的时间才把这些东西的来龙去脉给理个清楚兴奋之余想起了《康熙大帝》中那句抬起头来让朕瞧瞧的经典于是索性把题目改成了《ASPNET抬起头来让朕瞧瞧》
如今的程序员其审美观何等挑剔差异又何等巨大然ASPNET这位美女却独领风骚何哉?大凡我们说某某某美如果是外在的美那总是经不起时间的考验和众人对美的差异定位而如果是内在美则时间无法洗去其气质众人亦无旁词故欲知ASPNET美之何在当瞧其内在方可知晓
我在CSDN上逛的时候无意中发现了《[翻译]了解ASPNET底层架构doc》这篇文章看完之后一头雾水但又似乎意犹未尽于是耐心下来对于每一处有疑点的地方慢慢琢磨查资料向我的同事也是好友qwliang请教(我的很多疑惑点正是因为有他的指导和帮助才得以得到解决谢谢他)反反复复的看了几遍终于看懂了这篇文章也瞧见了ASPNET的美
我本来想针对自己已经形成的理解写一个系列但是考虑到近期时间比较紧而且最终写出来的东西大多还是剪刀+口水的产物还不如把自己的在分析分析aspnet底层运行原理过程中搜索到的比较有价值的一些资料共享上来大家仁者见仁智者见智我在后面附带介绍自己对这些文章的评价希望能帮助你理解分析
在分析的过程当中充分利用Reflector是必要的因为通过它你可以看到实际的代码(尽管不一定和源代码一模一样)如果说文字是有二义性的那么代码是没有的通过分析代码你可以更容易理解文字表达的内容
另外附上我的一些个人认识
几个名词解释
A: XX工厂(Factory)生成某个对象运用了工厂模式负责生成(生产)对象任务的对象叫做工厂工厂模式是一种构建模式通过附件你应该能够理解
B: CLR寄宿(Host) 不要被这个名词吓倒其实没有什么CLR寄宿实际上就是在非托管应用程序中加载CLR一个非托管应用程序(比如sql server)需要运行托管代码(比如C#写的存储过程)那么就需要在它的进程当中加载NET运行时CLR也就是说CLR要寄宿在运行sql server的进程当中
其实从生活中来看寄宿这个词也可以帮助你理解假如你和你的家人住在一起那我们不会说你寄宿在你家如果哪天你来了一个远房亲戚住在你家他就是寄宿在你家对于一个托管程序你用Dependency这个工具来看你会发现它的运行要依赖于MsCoreedll而对于一个非托管程序则应该不会看到这个依赖(Dependency只能看到静态依赖关系)因为寄宿CLR一般是通过LoadLibrary来动态加载的(这个我不敢肯定但是我看了好几个exe和dll都没有比如wwpexeinetInfoexe等)
关于寄宿的细节你可以参考《NET框架程序设计》(修订版)中的节《加载net运行时》和《CLR寄宿》
C: 应用程序域(AppDomain)应用程序域从逻辑上来说它类似于进程它是一个逻辑上的容器域的概念其实也就是一个范围的概念就好像以前的跑马圈地圈住一块地之后就说这是我的地域范围从实现上来说AppDomain也是System命名空间中的一个类你可以通过Reflector看到这个类的信息你也可以参考《NET框架程序设计》(修订版)中的《应用程序域》
D: 容器(Container) 容器就是包含其它对象的对象
E: 管道以前对管道的理解是两个进程通过管道来进行通信比如在IIS中inetinfoexe通过命名管道将请求交给aspnet_wpexe(之所以称为命名管道是因为给这个管道起了一个随机的名字)现在又出来了一个http 管道(http pipeline)但是这回却是在同一个进程(比如IIS中wwpexe)里面这是怎么回事?让我们来看看管道的本质我们分析一下实际生活中的管道我们看到管道具有下面两个特征
a 从里面流过的东西来看东西从管道一头进入从另外一头出来东西还是原来的东西
b 管道从外部形态来看它连通了两个不同的地方也就是说它代表着一种流向一种流程一种顺序
是的我们计算机中的术语和生活中的概念是相通的我们这里说的HTTP管道就是指Http ModuleHttp Handler这些对象而在这些HTTP管道流过的东西是同一个对象那就是Http Context对象在Http ModuleHttp Handler这些对象中对Http Context对象的处理不过是对Http Context对象中的内容进行改变(最大的改变就是给Response对象赋上内容)但是没有改变它的结构
几个容易造成误解的概念
A:Http Application和我们在页面中使用的Application对象这两者是不同的前者代表着我们整个应用程序对于我们的每个请求HttpApplicationFactory都会分配一个Http Application对象这个对象将管理着这个对请求的处理逻辑或者说它是事件调度中心你可以看到我们的Globalasax实际上就继承了HttpApplication我们在页面中使用的Application是一个状态的概念它是HttpApplicationState的一个实例并且是嵌在httpContext对象上的一个子对象
B:NET运行时和HTTP运行时NET运行时即是CLR它的核心是MsCorEEdll后者是HTTP RunTime它是Systemweb中httpRuntime类的实例HttpRuntime负责Http Application Http Context的创建和初始化等工作这两者是不同的
C: Http Application Http Context Http ModuleHttp Handler
对于每个请求都被路由到一个HttpApplication对象上HttpApplicationFactory类根据应用程序的负载为你的ASPNET应用创建一个HttpApplication对象池并为每个请求分发HttpApplication对象的引用
这里我再次强调HttpApplication的主要职责是作为Http管道的事件控制器httpApplication它本身对发送给应用程序的数据一无所知它只是一个通过事件来通讯的消息对象它触发事件并通过HttpContext对象来向被调用函数传递消息实际的当前请求的状态数据由HttpContext对象维护你可以用Reflector看一看HttpContext类里面包含着RequestResponseApplicationServerSession等表示状态的对象其实HttpContext本身也表示一种状态它还有两个很重要的属性Current和Items前者用来代表自己后者是可以存储任何对象的集合你不要小看后者它真的非常有用鑒于自己与Context曾经有过一段情史我将在以后写篇blog详细介绍它
httpModule有人说是它是监视器有人说是过滤器他们都是从不同角度来看httpModule所以都是对的httpModule提供了对请求进入http Handler处理之前的预处理和经过http handler处理后的事后处理既然可以预处理当然可以实现拦截请求不交给http handler去处理实现过滤的功能从另外一个角度上来说一旦有请求到来便会初始化httpModule(httpApplication中有负责初始化httpModule的InitModules()方法)当然也就意味着httpModule监视着请求(也就是监视器的来源)毕竟它是我们能够对请求进行处理的开始需要说明一点的是ASPNET只是为我们提供了这个能力你需要自己去添加事件代码来实现控制比如你可以在Globalasax中的事件处理函数中添加代码你也可以自己定义http module在附件4《aspnet framework深度历险pdf》你可以看到具体的实例至于http Handler我们的页面其实就是一个http Handler你可以从SystemWebUIPage类(我们所有页面的基类)的声明中看到它要实现IHttpHandler接口你可以翻阅《.NET程序设计技术内幕》这本书的《图形控件》看看自己定制实现http Handler的好处
但是我不同意在附件《aspnet framework深度历险pdf》中所说认为请求是一个单线流式的经过Http ApplicationFactory>Http Application> Http Module > Http Handler >…从附件《[翻译]了解ASPNET底层架构doc》的图也可以看到所有的处理起点是在最左边的ASPNET开始为什么呢?实际上Http Module和Http Handler都是嵌在Http
Application上的整个流程是由http Application进行调度的从另外一个角度上来说http Application的大部分功能都是由Http Module来实现的这些Http Module实际上就是在http Application启动并参与处理请求时被实例化的类你可以在webconfig中ttp Module> 看到预定义的http Module 包括会话验证等
最后预祝你也能抱得美人归