您的位置:首页 > 编程语言 > ASP

小弟浅谈asp.net页面生成周期---上

2012-08-26 19:43 225 查看
我们做web开发的,很有必要了解一下asp.net页面的生命周期,只有了解了他的原理,我们才能去更好的优化我们的网页(例如:验证用户信息、记录网站在线人生、防止图片外链、屏蔽IP及其页面静态化等操作,这些操作在什么时候执行最优),及其我们的网站出了问题去查到问题解决问题等。
首先我们要想了解asp.net的生命周期,就要抓住它内部的一条统领全局的命脉,通过这个命脉把这一切紧密的连接在了一起,如果你没有把握住的话,学起来,就会很散不知所云,了解了他之后,网站的访问模型:
请求----->处理---->响应 的过程也就好说了。
asp.net页面生存周期开始:
客户请求
第一:用户在浏览器的地址栏中输入请求的Url并回车,浏览器就会把我们请求的Url,封装成请求信息,并且建立socket通讯的套接字,分析Url并把请求发送到响应的服务器上

服务器处理
服务器端内部分为两个模块:分别是内核模块和用户模块
首先内核模块中的HTTP.SYS服务会监听服务器的80端口(默认的网站端口),当监听到有客户端的连接后,也是创建套接字与他通讯,并且解析请求的协议及其端口信息,解析出来后,去访问一下注册表(键值对),就知道应该把这个请求交给那个服务器端进程来处理(同时一般在IIS安装的时候就默认注册过这个过滤模块),查到后就把请求信息交给IIS处理

IIS大体上分为两部分,第一部分为主进程InetInfo.exe和服务进程w3svc他是继承在操作系统svchost.exe进程中。
一个IIS中可以有多个网站也就是多个工作进程,并且采用了应用程序池的技术,默认的IIS6.0的工作进程是w3wp.exe进程
其次IIS拿到请求信息之后,及其就是交给了w3svc服务,他会检查请求的文件的后缀,如果是静态的文件(html,js,css,jpg,png...)则直接处理返回,如果是动态的文件,就回去inetinfo.exe主进程中查看处理这种类型的动态文件的元数据(包括了那个工作进程和其中的扩展程序),如果是.aspx这种动态文件,就会交给池中的一个工作进程,中的aspnet_isapi.dll这个扩展处理(这个扩展程序是在安装.net Framework的时候注册的,并且这个扩展程序是非托管的程序集,com组件),这个扩展程序就是把请求信息从非托管程序交给托管程序进行处理的桥梁,aspnet_isapi.dll的主要作用是:查看.net Framework有没有启动(第一次请求网站的时候是没有启动的),没有启动就启动,并且把请求信息交给运行时去处理;
************************************************************************************************
当把请求信息交给运行时之后就真正的进入托管资源了,其后的代码及其处理过程我们都能看到

当请求到达ISAPIRuntime后,其实是交给了他的一个ProcessRequest(IntPtr ecb,int iWrTYpe)方法,这个方法中有一个ecb指针,他就指向了原始的请求信息(ecb是Windows操作系统中的一个句柄,就是Windows操作系统中的一种资源),通过这个ecb句柄,完成了请求信息从非托管资源到托管资源的交接;
在这个方法中拿到这个ecb后通过他创建了一个HttpWorkRequest wr实例(这个实例对原始的请求信息做了简单的封装,并且封装了ecb返回里面的返回数据,也就是说请求响应都通过他,交给了ecb)
在往下走,就把这个wr交给了HttpRuntime的一个ProcessRequestNoDemand(wr)方法,在这个方法中:
通过传递来的wr对象常见了一个包含了完成的请求响应信息的HttpContext上下文对象,也就是这个对象在整个Application管道中流过了整个管道模型,这个HttpContext对象中主要是包括了HttpRequest对象和HttpResponse对象,这两个对象,封装了请求和响应信息;
往下走,这个方法中就获取了一个维护管道的Application对象:
通过IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);
并且在这个GetApplicationInstance(context)方法中做了三件事:
第一:确保了global文件的编译(内部判断,如果没有编译,就编译这个文件)
第二:确保Application_Start方法的执行 theApplicationFactory.EnsureAppStartCalled(context)(这个方法是在网站第一次访问的时候才会执行,并且只执行一次,这个方法中主要是用来初始化一些静态的字段,或者静态的方法,当作全局用,其内部,维护了一个特殊的Application对象池,当执行EnsureAppStartCalled(context)方法的时候,他会去特殊的Application池 中去查找,如果池中有就pop出来一个,如果池中没有就去反射创建一个,并且把放入池中);
第三:return _theApplicationFactory.GetNormalApplicationInstance(context)从普通的Application池中拿到一个对象并且返回,如果这个池中没有,就通过第一步中编译global文件,得到他的元数据,并且反射创建一个Application对象,同时调用他的Init方法,当调用他的Init方法的时候,回去反射获取web.config中注册了的所有的HttpModel对象,创建所有的Model对象后执行HttpModel对象的Init方法,一般我们注册Application管道的19个事件的时候都会注册在HttpModel的Init方法中,当HttpModel的Init方法被调用的时候,我们注册的事件也就触发了

创建好了维护管道的Application实例后,接下来就是管道的流程了,HttpContext对象一值流过了所有的事件;简单的来说管道就是一个插件模型,对HttpContext上下文对象进行处理的过程。
在这个管道中程序员可以注册的19个事件:
下面是请求管道中的19个事件.

(1)BeginRequest: 开始处理请求

(2)AuthenticateRequest授权验证请求,获取用户授权信息

(3):PostAuthenticateRequest获取成功

(4): AunthorizeRequest 授权,一般来检查用户是否获得权限

(5):PostAuthorizeRequest:获得授权

(6):ResolveRequestCache:获取页面缓存结果

(7):PostResolveRequestCache 已获取缓存 当前请求映射到MvcHandler(pr): 创建控制器工厂 ,创建控制器,调用action执行,view→response

//action Handler : PR()

(8):PostMapRequestHandler 创建页面对象:创建 最终处理当前http请求的 Handler 实例: 第一从HttpContext中获取当前的PR Handler ,Create

(9):AcquireRequestState 开始获取Session

(10)PostAcquireRequestState 已经获得Session

(11)PreRequestHandlerExecute:准备执行页面对象
执行页面对象的ProcessRequest方法

(12)PostRequestHandlerExecute 执行完页面对象了

(13)ReleaseRequestState 释放请求状态

(14)PostReleaseRequestState 已释放请求状态

(15)UpdateRequestCache 更新缓存

(16)PostUpdateRequestCache 已更新缓存

(17)LogRequest 日志记录

(18)PostLogRequest 已完成日志

(19)EndRequest 完成、
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: