JavaWeb與Asp.net工作原理比較分析

來源:互聯網
上載者:User

標籤:jpg   publish   api   檔案   param   技術分享   引入   cat   維護   

一、概述

不管是什麼語言開發的web應用程式,都是在解決一個問題,那就是使用者輸入url怎麼把對應的頁面響應出來,如何通過url映射到響應的類,由於自己做asp.net的時間也不短了,還算是對asp.net的整個流程還算是瞭解,所以在自學JavaWeb的時候也很好奇JavaWeb中是如何處理的。

二、asp.net的工作原理

下面的對asp.net的工作流程的介紹(紅字)以及我個人的理解。這裡也給學asp.net的推薦一本書<<asp.net本質論>>,這本書對http請求流程講的比較詳細,也是一本挺不錯的書。

以IIS 6.0為例,在背景工作處理序w3wp.exe中,利用Aspnet_ispai.dll載入.NET運行時(如果.NET運行時尚未載入)。IIS 6引入了應用程式集區的概念,一個背景工作處理序對應著一個應用程式集區。一個應用程式集區可以承載一個或者多個Web應用,每個Web應用映射到一個IIS虛擬目錄。與IIS 5.x一樣,每一個Web應用運行在各自的應用程式定義域中。

是我本地電腦的IIS應用程式集區列表。

紅線部分也顯示的很清楚,應用程式集區與背景工作處理序相關聯,包含一個或多個應用程式,並提供不同應用之間的隔離。在我本地Test應用池中就有2個應用。具體建立可以參考Nginx負載平衡篇http://www.cnblogs.com/5ishare/p/6129775.html.

如果HTTP.SYS接收到的HTTP請求是對該Web應用的第一次訪問,當成功載入了運行時後,會通過AppDomainFactory為該Web應用建立一個應用程式定義域(AppDomain)。隨後,一個特殊的運行時IsapiRuntime被載入。IsapiRuntime定義在程式集System.Web中,對應的命名空間為System.Web.Hosting。IsapiRuntime會接管該HTTP請求。

這裡的應用程式定義域提供了四個重要的機制。

1.隔離  不同應用程式定義域直接不能直接存取

2.卸載   被載入的應用程式集只能以應用程式定義域為單位來卸載

3.安全  以應用程式定義域為邊界的安全機制

4.配置  以應用程式定義域為邊界的配置

IsapiRuntime會首先建立一個IsapiWorkerRequest對象,用於封裝當前的HTTP請求,並將該IsapiWorkerRequest對象傳遞給ASP.NET運行時:HttpRuntime,從此時起,HTTP請求正式進入了ASP.NET管道。根據IsapiWorkerRequest對象,HttpRuntime會建立用於表示當前HTTP請求的上下文(Context)對象:HttpContext。

IsapiWorkerRequest是比較底層的對象,HttpRuntime接到請求之後會將其分析拆解,建立HttpRequest、HttpResponse對象,一次Http請求需要好幾個對象,還有HttpServerUtility類型的對象處理網站虛擬路徑和伺服器檔案系統之間的映射關係,為了管理這些對象,定義了HttpContext來統一處理參數的表示問題。

隨著HttpContext被成功建立,HttpRuntime會利用HttpApplicationFactory建立新的或者擷取現有的HttpApplication對象。實際上,ASP.NET維護著一個HttpApplication對象池,HttpApplicationFactory從池中選取可用的HttpApplication使用者處理HTTP請求,處理完畢後將其釋放到對象池中。HttpApplicationFactory負責處理當前的HTTP請求。HttpRuntime建立HttpContext成功之後,會建立HttpApplication對象,需要注意的是HttpApplication對象建立的來源,一是通過HttpApplicationFactory建立一種是HttpApplication對象池擷取,它和Java Web中可不太一樣。JavaWeb中的Servlet是單例多線程,通過Servlet對象只建立一個,通過線程池來響應請求。

在HttpApplication初始化過程中,會根據設定檔載入並初始化相應的HttpModule對象。對於HttpApplication來說,在它處理HTTP請求的不同的階段會觸發不同的事件(Event),而HttpModule的意義在於通過註冊HttpApplication的相應的事件,將所需的操作注入整個HTTP請求的處理流程。ASP.NET的很多功能,比如身分識別驗證、授權、緩衝等,都是通過相應的HttpModule實現的。

當請求轉入ASP.NET管道後,最終負責處理該請求的是與請求資源類型相匹配的HttpHandler對象,但是在Handler正式工作之前,ASP.NET會先載入並初始化所有配置的HttpModule對象。HttpModule在初始化的過程中,會將一些功能註冊到HttpApplication相應的事件中,那麼在HttpApplication整個請求處理生命週期中的某個階段,相應的事件會被觸發,通過HttpModule註冊的事件處理常式也得以執行。所有的HttpModule都實現了IHttpModule介面。

這裡的HttpModule起到了過濾的功能,這就和JavaWeb的Filter有點類型,利用它們可以做一些例如許可權等一些處理。這種設計的好處也很明顯,擴充性很強,使用者可以自己選擇使用。

而最終完成對HTTP請求的處理實現在另一個重要的對象中:HttpHandler。對於不同的資源類型,具有不同的HttpHandler。比如.aspx頁對應的HttpHandler為System.Web.UI.Page,WCF的.svc檔案對應的HttpHandler為System.ServiceModel.Activation.HttpHandler。

HttpHander有點類似JavaWeb的Servlet,最終處理還是需要它們,而且都是web的基礎,JavaWeb中jsp最終還是會以Servlet對象來運行,asp.net中也是一樣。

三、JavaWeb的工作流程

上面asp.net主要是關於池子的問題,下面JavaWeb主要是關於容器的問題。

Tomcat 的容器分為四個等級,真正管理 Servlet 的容器是 Context 容器,一個 Context 對應一個 Web 工程。這裡有點類似asp.net的應用程式定義域。

一個 Web 應用程式對應一個 Context 容器,也就是 Servlet 運行時的 Servlet 容器,添加一個 Web 應用程式時將會建立一個 StandardContext 容器,並且給這個 Context 容器設定必要的參數。最重要的一個配置是 ContextConfig,這個類將會負責整個 Web 應用程式配置的解析工作,最後將這個 Context 容器加到父容器 Host 中。

1.其實我們在用eclipse將工程添加到tomcat伺服器的過程就是在執行上面的工作。注意下面紅線的部分,If server is started,publish changes immediately.伺服器啟動時,對Context 容器做的改變會立刻發布。能做到立刻發布,主要是靠觀察者設計模式的Listener。ContextConfig 繼承了 LifecycleListener 介面,所以對ContextConfig的修改也會立刻生效。

2.ContextConfig對象

關於ContextConfig對象,我們可以逆向的思考,我們建立一個Servlet類的同時需要在web.xml中進行配置servlet-name、servlet-calss、servlet-mapping、init-param,那Context容器又是怎麼知道它們的對應關係和初始化參數呢?於是ContextConfig出現了。找到了這麼多的初始化參數和映射關係,通過這些參數和映射將Servlet、Filter、Listener放入容器中,

3.Servlet執行個體化、初始化

上面雖然通過ContextConfig將Servlet各個初始化屬性添加到Context容器中,但並沒有將Servlet進行執行個體化初始化,所以還是不能使用。如果 Servlet 的 load-on-startup 配置項大於 0,那麼在 Context 容器啟動的時候就會被執行個體化。而執行個體化就要找到對應的類,對於jsp檔案實質也是Servlet,servletClass 就是 conf/web.xml 中定義的 org.apache.jasper.servlet.JspServlet。而Servlet對象只會建立、初始化一次,如果有多個請求同時訪問,會從線程池中擷取一個線程還是用這個Servlet對象處理使用者請求,算是單例多線程,這就會帶來一個問題,安全執行緒問題,訪問特別是修改Servlet類中的全域變數時會導致資料錯誤,所以盡量不使用在Servlet類中聲明全域變數。實在不行就需要給線程加鎖。

4.Servlet的生命週期

生命週期這個詞在開發中很常見,Servlet也不例外。

Servlet 生命週期:Servlet 載入--->執行個體化(init())--->服務(Service())--->銷毀(destroy())。

載入和執行個體化已在tomcat啟動的時候完成,當用戶端發起請求,Servlet是調用service()方法對請求進行響應的,service()方法中對請求的方式進行了匹配,選擇調用doGet,doPost等這些方法,然後再進入對應的方法中調用邏輯層的方法,實現對客戶的響應.

destroy(): 僅執行一次,在伺服器端停止且卸載Servlet時執行該方法。當Servlet對象退出生命週期時,負責釋放佔用的資源。一個Servlet在運行service()方法時可能會產生其他的線程,因此需要確認在調用destroy()方法時,這些線程已經終止或完成.

5.Servlet的繼承關係

我們建立的每一次Servlet都是繼承abstract HttpServlet,而HttpServlet 又繼承了javax.servlet.GenericServlet。GenericServlet是一個通用的,不特定於任何協議的Servlet,它實現了Servlet介面.

Servlet介面和GenericServlet是不特定於任何協議的,而HttpServlet是特定於HTTP協議的類,所以HttpServlet中實現了service()方法,並將請求ServletRequest、ServletResponse 強轉為HttpRequest 和 HttpResponse。

JavaWeb與Asp.net工作原理比較分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.