亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ASP.NET管線與應用程序生命周期

系統 2511 0
ASP.NET Web編程原理 之

8.2 ASP.NET 管線與應用程序生命周期

8.1 節介紹了 IIS 的系統架構和 HTTP 請求處理的總體流程,從中可以知道每個 ASP.NET 網站都對應著一個 Web 應用程序,此 Web 應用程序可以響應 HTTP 請求,為用戶提供所需的信息。那么, ASP.NET 應用程序具體是如何響應 HTTP 請求的?包括哪些具體的處理流程?這涉及到 ASP.NET 應用程序的生命周期問題。

8.2.1 ASP.NET應用程序生命周期*

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

1 瀏覽器發出訪問某 ASP.NET 網頁的 HTTP 請求

假設這個請求是針對此網頁所屬的 ASP.NET 應用程序的第一次請求。

當此請求到達 Web 服務器時,由 HTTP.SYS 負責接收,根據此請求的 URL HTTP.SYS 將其傳遞給此 ASP.NET 應用程序所對應的應用程序池,由在此應用程序池中運行的工作者進程負責處理請求 [1]

工作者進程接收到這個請求之后,裝載專用于處理 ASP.NET 頁面的一個 ISAPI 擴展“ aspnet_isapi.dll ”,并將 HTTP 請求傳給它。

工作者進程加載完 aspnet_isapi.dll 后,由 aspnet_isapi.dll 負責加載 ASP.NET 應用程序的運行環境―― CLR [2] 。 

工作者進程工作于非托管環境(指 Windows 操作系統本身)之中,而 .NET 中的對象則工作于托管環境(指 CLR )之中, aspnet_isapi.dll 起到了一個溝通兩者的橋梁作用,將收到的 HTTP 請求(由非托管環境傳來)轉發給相應 .NET 對象(處于托管環境中)處理。

2 創建 ApplicationManager 對象和應用程序域

加載 CLR 之后,由 ApplicationManager 類負責創建一個應用程序域。每個 ASP.NET 應用程序都運行于自己的應用程序域中,由唯一的應用程序標識符標識。

每個應用程序域都對應著一個 ApplicationManager 類的實例,由它來負責管理運行在域中的 ASP.NET 應用程序(比如啟動和停止一個 ASP.NET 應用程序,在指定的 ASP.NET 應用程序中創建對象等等)。

3 創建 HostingEnvironment 對象

在為 ASP.NET 應用程序創建應用程序域的同時,會創建一個 HostingEnvironment 對象,此對象提供了 ASP.NET 應用程序的一些管理信息(比如 ASP.NET 應用程序的標識,對應的虛擬目錄和物理目錄),并提供了一些附加的功能(比如在應用程序域中注冊一個對象,模擬特定的用戶等等)。

4 為每個請求創建 ASP.NET 核心對象

當應用程序域創建完成之后,一個 ISAPIRuntime 對象被創建,并自動調用它的 ProcessRequest() 方法。在此方法中, ISAPIRuntime 對象根據傳入的 HTTP 請求創建一個 HttpWorkerRequest 對象,此對象以面向對象的方式包裝了 HTTP 請求的各種信息(這就是說, 原始的 HTTP 請求信息被封裝為 HttpWorkerRequest 對象 )。然后,調用 ISAPIRuntime 對象的 StartProcessing() 方法啟動整個 HTTP 請求處理過程(此即“ HTTP 管線: HTTP Pipeline ),在這個處理過程的開端,一個 HttpRuntime 類型的對象被創建,前面創建好的 HttpWorkerRequest 對象作為方法參數被傳送給此 HttpRuntime 對象的 ProcessRequest() 方法。

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

HttpRuntime 類的 ProcessRequest() 方法根據 HttpWorkerRequest 對象中所提供的 HTTP 請求信息,創建了一個 HttpContext 對象。

HttpContext 對象之所以重要,是因為此對象包容了另兩個在 ASP.NET 編程中非常常見的對象: HttpResponse HttpRequest

HttpRequest 對象中的信息來自于原始的 HTTP 請求,比如它的 Url 屬性就代表了原始 HTTP 請求信息中的 URL

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

Page 類提供了相應的屬性來引用這兩個對象,因此在 ASP.NET 網頁中可以直接使用“ Requset ”和“ Response ”屬性來訪問這兩個對象。例如:

<?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 對象,因此,上述代碼也可以改寫為以下形式:

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

{

protected void Page_Load(object sender, EventArgs e)

{

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

}

}

關于 HttpContext HttpResponse HttpRequest 這三個對象,必須掌握以下的要點:

l HttpContext 對象包容 HttpResponse HttpRequest 這兩個對象,可以從 HttpRequest 對象獲取 HTTP 請求的相關信息,而要向瀏覽器輸出的內容可以通過調用 HttpResponse 的方法實現。

l 針對每個 HTTP 請求, ASP.NET 都會創建一個 HttpContext 對象,在整個 HTTP 處理過程中,此對象都是可以訪問的。

5 分配一個 HttpApplication 對象用于處理請求

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

H ttpApplicationFactory 對象負責管理 一個 HttpApplication 對象池 [4] ,當有 HTTP 請求到來時,如果池中還有可用的 HttpApplication 對象,就直接分配此對象用于處理 HTTP 請求,否則,創建一個新的 HttpApplication 對象。

6 HttpApplication 對象啟動 HTTP 管線

HttpApplication 對象負責裝配出整個“ HTTP 請求處理管線( HTTP Pipeline ”,可以將“ HTTP 請求處理管線”與現代工廠中的“生產流水線”做個類比。前面步驟中創建好的 HttpContext 對象就是這個生產流水線要加工的“產品”,當它流經“生產流水線”的不同部分時,將被進行特定的加工和處理過程。

這些特定的“加工和處理過程”是怎樣進行的?

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

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

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

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

每個被訪問的 ASP.NET 頁面都會被轉換為一個“ 派生自 Page 類的頁面類

注意: Page 類實現了 IHttpHandler 接口,此接口定義了一個 ProcessRequest() 方法。

ASP.NET 頁面類生成以后被自動編譯為程序集,然后其 ProcessRequest() 方法被自動調用(因為 Page 類實現了 IHttpHandler 接口,所以肯定有此方法)。在此方法中, Web 軟件工程師編寫的代碼被執行(如果有的話)。 ProcessRequest() 方法的執行結果再次被 HttpContext 對象所承載,控制又轉回到“ HTTP 請求處理流水線”中, HttpApplication 對象繼續激發后繼的事件。這時,如果還有特定的 HTTP 模塊響應這些事件,則它們會被自動調用。

HttpContext 對象帶著最后的處理結果來到了“ HTTP 請求處理管線”的未端,其信息被取出來,再次以 aspnet_isapi.dll 為橋梁傳送給工作者進程。工作者進程再將 HTTP 請求的處理結果轉給 HTTP.SYS ,由它負責將結果返回給瀏覽器。

根據前面的介紹,可以將整個 Http 管線分成三段: 預處理階段 à 處理階段 à 后處理階段 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 管線的三個階段

8 ? 14 所示, HTTP 管線的預處理和后處理階段主要由多個 HTTP 模塊參與,通過事件來驅動,這兩個階段完成的工作主要是對 HttpContext 對象的各種屬性進行修改。

HTTP 請求的處理過程最終是由一個實現 IHttpHandler 接口的對象在“處理階段”完成的。每一個 ASP.NET 網頁生成的頁面類都實現了此接口。創建出合適的 HTTP 請求處理對象的工作由 PageHandlerFactory 對象 [9] 負責完成。

由此可見,實現了 IHttpHandler 接口的對象負責處理 HTTP 請求,這就是它被稱為“ Handler (處理程序)”的原因。

除了最常見的 ASP.NET 網頁之外, Web 軟件工程師還可以創建自己的實現了 IHttpHandler 接口的對象,并將其插入到 HTTP 管線中用于處理 HTTP 請求。

HTTP 請求處理完畢,相關的對象被釋放,但創建的應用程序域,以及 HttpApplication 等對象仍然存活,以響應下一次 HTTP 請求。

7 ASP.NET 應用程序生命周期小結

本節中介紹了 ASP.NET 應用程序的生命周期,這是一個相當復雜的過程,也許用以下通俗的類比更容易理解:

l HTTP 請求處理管線”就是一條現代工廠中的“生產流水線”, HttpContext 對象就是這條流水線上要加工的產品。

l HttpHandler HTTP 處理程序)對象是整個“產品生產線”的核心,由它負責將產品裝配成形。

l HttpModule HTTP 模塊)相當于“生產線”上的輔助工人,他們對產品( HttpContext 對象)進行“預處理”(為裝配產品作準備)和“后處理”(為產品出廠作準備,比如貼商標)。

l HttpApplication 對象是整個“生產線”的“領導” ,他負責給“生產線”分配工人(初始化并裝載所有注冊的 HttpModule ),然后會激發一系列的事件(被稱為“ ASP.NE T 應用程序事件”),特定的 HttpModule 負責響應特定的事件。



[1] 如果工作者進程不存在,則 IIS 監控程序 WAS 會創建一個,否則,復用已有的工作者進程。

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

[3] “類的實例”與“類的對象”含義等同,都是指以類為模板創建出來的對象。

[4] 對象池( object pool )是面向對象軟件系統常見的一種對象組織方式,可以將其看成是一個對象容器。對象池中放有事先創建好的多個對象。當外界需要某個對象時,可以直接從池中取出一個現成的對象使用,這就避免了頻繁創建對象所帶來的性能損失。

[5] HttpApplication 定義了相當多的事件,完整的事件清單請查看 MSDN

[6] 此方法會在獲取 HttpApplication 對象時被自動調用。

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

[8] 通過在 Web.Config 中插入特定的內容可以將自定義的 HTTP 模塊加入到 HTTP 請求的處理流程中。

[9] 這是 ASP.NET 技術框架中的另一個核心類。

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

本系列文章結束語:

理解Http PipeLine在ASP.NET編程中有著重要的意義,只有對它有所了解,才能理解開發中遇到的種種問題,并為學習和掌握更復雜的Web開發技術(比如自定義HttpModule和HttpHandler)打下基礎。

到此為止,有關ASP.NET Web編程原理的系列文章就貼完了。之所以只貼這部分,是因為我發現許多ASP.NET技術書籍對這一部分內容都語焉不詳,一帶而過,而這一部分又是非常重要的,期望這四篇文章能對大家有所幫助。其他的常規內容絕大多數ASP.NET技術書籍都有,就不再贅述了。

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

祝大家學習順利。

金旭亮

2008年國慶于北京

ASP.NET管線與應用程序生命周期


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久草新免费 | 四虎影视永久地址www成人 | 青青国产成人久久91网 | 久久99深爱久久99精品 | 久久99网站 | 在线麻豆| 激情在线观看视频 | 久9久9精品视频在线观看 | 欧美国产高清 | 国产系列 视频二区 | 国产精品免费看久久久香蕉 | 国产欧美日韩综合二区三区 | 久久视频精品a线视频在线观看 | 中文字幕日本在线 | 九九九九精品视频在线播放 | 日本精品一区二区三本中文 | 在线观看人成网站深夜免费 | 六月色婷婷 | 国产欧美日本在线观看 | 国产精品自在线天天看片 | 夜夜夜夜猛噜噜噜噜噜 | 天天色网站 | 在线韩日| 狠狠操大逼 | 日日碰日日摸日日澡视频播放 | 成人国产亚洲欧美成人综合网 | 91精品成人免费国产片 | 国内精品一区二区 | 亚洲精品福利在线 | 欧美日韩中文一区二区三区 | 99国产精品热久久久久久夜夜嗨 | 午夜男人影院 | 青青青爽在线视频观看大全 | 日日爽夜夜爽 | 高清色视频 | 国产精品久久大陆 | 77奇米影视 | 国产精品爱久久久久久久 | 欧美一区二区影院 | 福利在线国产 | 欧美 日韩 高清 |