日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

ASP.NET管線與應(yīng)用程序生命周期

系統(tǒng) 2717 0
ASP.NET Web編程原理 之

8.2 ASP.NET 管線與應(yīng)用程序生命周期

8.1 節(jié)介紹了 IIS 的系統(tǒng)架構(gòu)和 HTTP 請(qǐng)求處理的總體流程,從中可以知道每個(gè) ASP.NET 網(wǎng)站都對(duì)應(yīng)著一個(gè) Web 應(yīng)用程序,此 Web 應(yīng)用程序可以響應(yīng) HTTP 請(qǐng)求,為用戶提供所需的信息。那么, ASP.NET 應(yīng)用程序具體是如何響應(yīng) HTTP 請(qǐng)求的?包括哪些具體的處理流程?這涉及到 ASP.NET 應(yīng)用程序的生命周期問(wèn)題。

8.2.1 ASP.NET應(yīng)用程序生命周期*

本節(jié)以 IIS 6 為例分步介紹 ASP.NET 應(yīng)用程序處理 HTTP 請(qǐng)求的處理流程。 IIS 7 的處理過(guò)程與 IIS 6 相比有些小變化,但總體上是一致的。

1 瀏覽器發(fā)出訪問(wèn)某 ASP.NET 網(wǎng)頁(yè)的 HTTP 請(qǐng)求

假設(shè)這個(gè)請(qǐng)求是針對(duì)此網(wǎng)頁(yè)所屬的 ASP.NET 應(yīng)用程序的第一次請(qǐng)求。

當(dāng)此請(qǐng)求到達(dá) Web 服務(wù)器時(shí),由 HTTP.SYS 負(fù)責(zé)接收,根據(jù)此請(qǐng)求的 URL HTTP.SYS 將其傳遞給此 ASP.NET 應(yīng)用程序所對(duì)應(yīng)的應(yīng)用程序池,由在此應(yīng)用程序池中運(yùn)行的工作者進(jìn)程負(fù)責(zé)處理請(qǐng)求 [1]

工作者進(jìn)程接收到這個(gè)請(qǐng)求之后,裝載專用于處理 ASP.NET 頁(yè)面的一個(gè) ISAPI 擴(kuò)展“ aspnet_isapi.dll ”,并將 HTTP 請(qǐng)求傳給它。

工作者進(jìn)程加載完 aspnet_isapi.dll 后,由 aspnet_isapi.dll 負(fù)責(zé)加載 ASP.NET 應(yīng)用程序的運(yùn)行環(huán)境―― CLR [2] 。 

工作者進(jìn)程工作于非托管環(huán)境(指 Windows 操作系統(tǒng)本身)之中,而 .NET 中的對(duì)象則工作于托管環(huán)境(指 CLR )之中, aspnet_isapi.dll 起到了一個(gè)溝通兩者的橋梁作用,將收到的 HTTP 請(qǐng)求(由非托管環(huán)境傳來(lái))轉(zhuǎn)發(fā)給相應(yīng) .NET 對(duì)象(處于托管環(huán)境中)處理。

2 創(chuàng)建 ApplicationManager 對(duì)象和應(yīng)用程序域

加載 CLR 之后,由 ApplicationManager 類負(fù)責(zé)創(chuàng)建一個(gè)應(yīng)用程序域。每個(gè) ASP.NET 應(yīng)用程序都運(yùn)行于自己的應(yīng)用程序域中,由唯一的應(yīng)用程序標(biāo)識(shí)符標(biāo)識(shí)。

每個(gè)應(yīng)用程序域都對(duì)應(yīng)著一個(gè) ApplicationManager 類的實(shí)例,由它來(lái)負(fù)責(zé)管理運(yùn)行在域中的 ASP.NET 應(yīng)用程序(比如啟動(dòng)和停止一個(gè) ASP.NET 應(yīng)用程序,在指定的 ASP.NET 應(yīng)用程序中創(chuàng)建對(duì)象等等)。

3 創(chuàng)建 HostingEnvironment 對(duì)象

在為 ASP.NET 應(yīng)用程序創(chuàng)建應(yīng)用程序域的同時(shí),會(huì)創(chuàng)建一個(gè) HostingEnvironment 對(duì)象,此對(duì)象提供了 ASP.NET 應(yīng)用程序的一些管理信息(比如 ASP.NET 應(yīng)用程序的標(biāo)識(shí),對(duì)應(yīng)的虛擬目錄和物理目錄),并提供了一些附加的功能(比如在應(yīng)用程序域中注冊(cè)一個(gè)對(duì)象,模擬特定的用戶等等)。

4 為每個(gè)請(qǐng)求創(chuàng)建 ASP.NET 核心對(duì)象

當(dāng)應(yīng)用程序域創(chuàng)建完成之后,一個(gè) ISAPIRuntime 對(duì)象被創(chuàng)建,并自動(dòng)調(diào)用它的 ProcessRequest() 方法。在此方法中, ISAPIRuntime 對(duì)象根據(jù)傳入的 HTTP 請(qǐng)求創(chuàng)建一個(gè) HttpWorkerRequest 對(duì)象,此對(duì)象以面向?qū)ο蟮姆绞桨b了 HTTP 請(qǐng)求的各種信息(這就是說(shuō), 原始的 HTTP 請(qǐng)求信息被封裝為 HttpWorkerRequest 對(duì)象 )。然后,調(diào)用 ISAPIRuntime 對(duì)象的 StartProcessing() 方法啟動(dòng)整個(gè) HTTP 請(qǐng)求處理過(guò)程(此即“ HTTP 管線: HTTP Pipeline ),在這個(gè)處理過(guò)程的開(kāi)端,一個(gè) HttpRuntime 類型的對(duì)象被創(chuàng)建,前面創(chuàng)建好的 HttpWorkerRequest 對(duì)象作為方法參數(shù)被傳送給此 HttpRuntime 對(duì)象的 ProcessRequest() 方法。

HttpRuntime 類的 ProcessRequest() 方法中完成了一些非常重要的工作,其中與 Web 軟件工程師關(guān)系最緊密的是:

HttpRuntime 類的 ProcessRequest() 方法根據(jù) HttpWorkerRequest 對(duì)象中所提供的 HTTP 請(qǐng)求信息,創(chuàng)建了一個(gè) HttpContext 對(duì)象。

HttpContext 對(duì)象之所以重要,是因?yàn)榇藢?duì)象包容了另兩個(gè)在 ASP.NET 編程中非常常見(jiàn)的對(duì)象: HttpResponse HttpRequest

HttpRequest 對(duì)象中的信息來(lái)自于原始的 HTTP 請(qǐng)求,比如它的 Url 屬性就代表了原始 HTTP 請(qǐng)求信息中的 URL

HttpResponse 對(duì)象則擁有一些屬性和方法,用于生成要返回給瀏覽器的信息。

Page 類提供了相應(yīng)的屬性來(lái)引用這兩個(gè)對(duì)象,因此在 ASP.NET 網(wǎng)頁(yè)中可以直接使用“ Requset ”和“ Response ”屬性來(lái)訪問(wèn)這兩個(gè)對(duì)象。例如:

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

Response .Write( Request .Url);

}

}

Page 類的 Context 屬性引用 HttpContext 對(duì)象,因此,上述代碼也可以改寫為以下形式:

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

this.Context.Response .Write( this.Context.Request .Url);

}

}

關(guān)于 HttpContext HttpResponse HttpRequest 這三個(gè)對(duì)象,必須掌握以下的要點(diǎn):

l HttpContext 對(duì)象包容 HttpResponse HttpRequest 這兩個(gè)對(duì)象,可以從 HttpRequest 對(duì)象獲取 HTTP 請(qǐng)求的相關(guān)信息,而要向?yàn)g覽器輸出的內(nèi)容可以通過(guò)調(diào)用 HttpResponse 的方法實(shí)現(xiàn)。

l 針對(duì)每個(gè) HTTP 請(qǐng)求, ASP.NET 都會(huì)創(chuàng)建一個(gè) HttpContext 對(duì)象,在整個(gè) HTTP 處理過(guò)程中,此對(duì)象都是可以訪問(wèn)的。

5 分配一個(gè) HttpApplication 對(duì)象用于處理請(qǐng)求

HttpRuntime 類的 ProcessRequest() 方法除了創(chuàng)建 HttpContext 對(duì)象之外,還完成了另一個(gè)很重要的工作——向 H ttpApplicationFactory 類的一個(gè)實(shí)例 [3] 申請(qǐng) 分配一個(gè) HttpApplication 對(duì)象用于管理整個(gè) HTTP 請(qǐng)求處理管線中的各種事件。

H ttpApplicationFactory 對(duì)象負(fù)責(zé)管理 一個(gè) HttpApplication 對(duì)象池 [4] ,當(dāng)有 HTTP 請(qǐng)求到來(lái)時(shí),如果池中還有可用的 HttpApplication 對(duì)象,就直接分配此對(duì)象用于處理 HTTP 請(qǐng)求,否則,創(chuàng)建一個(gè)新的 HttpApplication 對(duì)象。

6 HttpApplication 對(duì)象啟動(dòng) HTTP 管線

HttpApplication 對(duì)象負(fù)責(zé)裝配出整個(gè)“ HTTP 請(qǐng)求處理管線( HTTP Pipeline ”,可以將“ HTTP 請(qǐng)求處理管線”與現(xiàn)代工廠中的“生產(chǎn)流水線”做個(gè)類比。前面步驟中創(chuàng)建好的 HttpContext 對(duì)象就是這個(gè)生產(chǎn)流水線要加工的“產(chǎn)品”,當(dāng)它流經(jīng)“生產(chǎn)流水線”的不同部分時(shí),將被進(jìn)行特定的加工和處理過(guò)程。

這些特定的“加工和處理過(guò)程”是怎樣進(jìn)行的?

簡(jiǎn)單地說(shuō), HttpContext 對(duì)象經(jīng)過(guò)“生產(chǎn)流水線”的不同部分時(shí), HttpApplication 對(duì)象會(huì)先后激發(fā)出一連串的事件 [5] 。一種特定的組件—— HTTP 模塊( HTTP Module )可以響應(yīng)這些事件,在此事件響應(yīng)代碼中可以對(duì) HttpContext 對(duì)象進(jìn)行“加工和處理”,從這個(gè)意義上說(shuō), HTTP 模塊可以看成是“生產(chǎn)流水線”中的工人。 HTTP 模塊其實(shí)就是前面所介紹過(guò)的“ ISAPI 篩選器”。

HTTP 模塊對(duì)象是在 HttpApplication 對(duì)象的 InitModules() 方法 [6] 中被創(chuàng)建的,我們一般在 HTTP 模塊對(duì)象 Init() 方法 [7] 中書(shū)寫代碼使其可以響應(yīng) HttpApplication 對(duì)象所激發(fā)的特定事件。

ASP.NET 提供了一些預(yù)定義的 HTTP 模塊響應(yīng)特定的事件, Web 軟件工程師也可以編寫自己的 HTTP 模塊并將其插入到“ HTTP 請(qǐng)求處理管線”中 [8]

在流水線的中部(處理完了相關(guān)的事件), HttpContext 對(duì)象被最終的 Page 對(duì)象所接收(這就是為何可以在 ASP.NET 頁(yè)面中通過(guò) Page 類定義的 Context 屬性訪問(wèn) HttpContext 對(duì)象的原因)。

每個(gè)被訪問(wèn)的 ASP.NET 頁(yè)面都會(huì)被轉(zhuǎn)換為一個(gè)“ 派生自 Page 類的頁(yè)面類

注意: Page 類實(shí)現(xiàn)了 IHttpHandler 接口,此接口定義了一個(gè) ProcessRequest() 方法。

ASP.NET 頁(yè)面類生成以后被自動(dòng)編譯為程序集,然后其 ProcessRequest() 方法被自動(dòng)調(diào)用(因?yàn)? Page 類實(shí)現(xiàn)了 IHttpHandler 接口,所以肯定有此方法)。在此方法中, Web 軟件工程師編寫的代碼被執(zhí)行(如果有的話)。 ProcessRequest() 方法的執(zhí)行結(jié)果再次被 HttpContext 對(duì)象所承載,控制又轉(zhuǎn)回到“ HTTP 請(qǐng)求處理流水線”中, HttpApplication 對(duì)象繼續(xù)激發(fā)后繼的事件。這時(shí),如果還有特定的 HTTP 模塊響應(yīng)這些事件,則它們會(huì)被自動(dòng)調(diào)用。

HttpContext 對(duì)象帶著最后的處理結(jié)果來(lái)到了“ HTTP 請(qǐng)求處理管線”的未端,其信息被取出來(lái),再次以 aspnet_isapi.dll 為橋梁傳送給工作者進(jìn)程。工作者進(jìn)程再將 HTTP 請(qǐng)求的處理結(jié)果轉(zhuǎn)給 HTTP.SYS ,由它負(fù)責(zé)將結(jié)果返回給瀏覽器。

根據(jù)前面的介紹,可以將整個(gè) Http 管線分成三段: 預(yù)處理階段 à 處理階段 à 后處理階段 8 ? 14 )。

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 222.75pt" o:ole="" type="#_x0000_t75"><imagedata o:title="" src="file:///C:/Users/JINXUL~1/AppData/Local/Temp/msohtmlclip1/01/clip_image001.emz"></imagedata></shape>

HTTP Pipeline 8 ? 14 HTTP 管線的三個(gè)階段

8 ? 14 所示, HTTP 管線的預(yù)處理和后處理階段主要由多個(gè) HTTP 模塊參與,通過(guò)事件來(lái)驅(qū)動(dòng),這兩個(gè)階段完成的工作主要是對(duì) HttpContext 對(duì)象的各種屬性進(jìn)行修改。

對(duì) HTTP 請(qǐng)求的處理過(guò)程最終是由一個(gè)實(shí)現(xiàn) IHttpHandler 接口的對(duì)象在“處理階段”完成的。每一個(gè) ASP.NET 網(wǎng)頁(yè)生成的頁(yè)面類都實(shí)現(xiàn)了此接口。創(chuàng)建出合適的 HTTP 請(qǐng)求處理對(duì)象的工作由 PageHandlerFactory 對(duì)象 [9] 負(fù)責(zé)完成。

由此可見(jiàn),實(shí)現(xiàn)了 IHttpHandler 接口的對(duì)象負(fù)責(zé)處理 HTTP 請(qǐng)求,這就是它被稱為“ Handler (處理程序)”的原因。

除了最常見(jiàn)的 ASP.NET 網(wǎng)頁(yè)之外, Web 軟件工程師還可以創(chuàng)建自己的實(shí)現(xiàn)了 IHttpHandler 接口的對(duì)象,并將其插入到 HTTP 管線中用于處理 HTTP 請(qǐng)求。

當(dāng) HTTP 請(qǐng)求處理完畢,相關(guān)的對(duì)象被釋放,但創(chuàng)建的應(yīng)用程序域,以及 HttpApplication 等對(duì)象仍然存活,以響應(yīng)下一次 HTTP 請(qǐng)求。

7 ASP.NET 應(yīng)用程序生命周期小結(jié)

本節(jié)中介紹了 ASP.NET 應(yīng)用程序的生命周期,這是一個(gè)相當(dāng)復(fù)雜的過(guò)程,也許用以下通俗的類比更容易理解:

l HTTP 請(qǐng)求處理管線”就是一條現(xiàn)代工廠中的“生產(chǎn)流水線”, HttpContext 對(duì)象就是這條流水線上要加工的產(chǎn)品。

l HttpHandler HTTP 處理程序)對(duì)象是整個(gè)“產(chǎn)品生產(chǎn)線”的核心,由它負(fù)責(zé)將產(chǎn)品裝配成形。

l HttpModule HTTP 模塊)相當(dāng)于“生產(chǎn)線”上的輔助工人,他們對(duì)產(chǎn)品( HttpContext 對(duì)象)進(jìn)行“預(yù)處理”(為裝配產(chǎn)品作準(zhǔn)備)和“后處理”(為產(chǎn)品出廠作準(zhǔn)備,比如貼商標(biāo))。

l HttpApplication 對(duì)象是整個(gè)“生產(chǎn)線”的“領(lǐng)導(dǎo)” ,他負(fù)責(zé)給“生產(chǎn)線”分配工人(初始化并裝載所有注冊(cè)的 HttpModule ),然后會(huì)激發(fā)一系列的事件(被稱為“ ASP.NE T 應(yīng)用程序事件”),特定的 HttpModule 負(fù)責(zé)響應(yīng)特定的事件。



[1] 如果工作者進(jìn)程不存在,則 IIS 監(jiān)控程序 WAS 會(huì)創(chuàng)建一個(gè),否則,復(fù)用已有的工作者進(jìn)程。

[2] IIS 7 集成模式下,由于 CLR 是預(yù)加載的,所以這一步就不需要了。

[3] “類的實(shí)例”與“類的對(duì)象”含義等同,都是指以類為模板創(chuàng)建出來(lái)的對(duì)象。

[4] 對(duì)象池( object pool )是面向?qū)ο筌浖到y(tǒng)常見(jiàn)的一種對(duì)象組織方式,可以將其看成是一個(gè)對(duì)象容器。對(duì)象池中放有事先創(chuàng)建好的多個(gè)對(duì)象。當(dāng)外界需要某個(gè)對(duì)象時(shí),可以直接從池中取出一個(gè)現(xiàn)成的對(duì)象使用,這就避免了頻繁創(chuàng)建對(duì)象所帶來(lái)的性能損失。

[5] HttpApplication 定義了相當(dāng)多的事件,完整的事件清單請(qǐng)查看 MSDN

[6] 此方法會(huì)在獲取 HttpApplication 對(duì)象時(shí)被自動(dòng)調(diào)用。

[7] 所有 HTTP 模塊都要實(shí)現(xiàn) IHttpModule 接口, Init() 方法由此接口所定義。

[8] 通過(guò)在 Web.Config 中插入特定的內(nèi)容可以將自定義的 HTTP 模塊加入到 HTTP 請(qǐng)求的處理流程中。

[9] 這是 ASP.NET 技術(shù)框架中的另一個(gè)核心類。

*******************************************

本系列文章結(jié)束語(yǔ):

理解Http PipeLine在ASP.NET編程中有著重要的意義,只有對(duì)它有所了解,才能理解開(kāi)發(fā)中遇到的種種問(wèn)題,并為學(xué)習(xí)和掌握更復(fù)雜的Web開(kāi)發(fā)技術(shù)(比如自定義HttpModule和HttpHandler)打下基礎(chǔ)。

到此為止,有關(guān)ASP.NET Web編程原理的系列文章就貼完了。之所以只貼這部分,是因?yàn)槲野l(fā)現(xiàn)許多ASP.NET技術(shù)書(shū)籍對(duì)這一部分內(nèi)容都語(yǔ)焉不詳,一帶而過(guò),而這一部分又是非常重要的,期望這四篇文章能對(duì)大家有所幫助。其他的常規(guī)內(nèi)容絕大多數(shù)ASP.NET技術(shù)書(shū)籍都有,就不再贅述了。

本文如有錯(cuò)誤及疏漏之處,也懇求高手指出。

祝大家學(xué)習(xí)順利。

金旭亮

2008年國(guó)慶于北京

ASP.NET管線與應(yīng)用程序生命周期


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 运城市| 余姚市| 武强县| 社旗县| 石楼县| 唐河县| 三亚市| 郯城县| 临沂市| 皋兰县| 东安县| 夏津县| 武清区| 华宁县| 泰安市| 永济市| 莱阳市| 南和县| 辰溪县| 丹棱县| 虎林市| 宜州市| 礼泉县| 朔州市| 加查县| 法库县| 丰县| 登封市| 合肥市| 电白县| 蒙自县| 凤山市| 雷山县| 乌兰县| 奉贤区| 夏津县| 宜兰县| 玉山县| 齐齐哈尔市| 富民县| 东乌珠穆沁旗|