詳解Java開發Web應用程序的底層原理

前言

前面一篇文章,我從整個應用程序的整體以及跟運行環境的關係簡單聊了一下我們現在常用的Spring框架的設計基礎和原則,其中主要是控制反轉和依賴注入,以及容器化編程等概念。

這裏我不想去複述這些概念的定義,因爲那些東西網上隨便都能百度到,我想通過我的描述將這些概念串聯起來,讓大家更好的去立即它們知道爲什麼要這樣去做,我們每天開發使用的框架到底是個什麼東西,它的設計思想以及規範的由來。做到知其然還知其所以然,能夠讓我們在開發過程中更好的去使用它們,面對問題知道它大概的解決方向。

本文我想繼續沿着前面的思路來談談基於Web的應用程序需要使用Spring框架的容器化管理開發相關的理解。

Web應用程序與Servlet規範

當然說起應用程序開發來,我們都熟悉,現在應用程序有很多種分類,最初的控制檯程序,服務組件程序,到桌面應用程序,到基於HTTP訪問協議的web應程序等。

其實它們的本質就是基於某種輸入/輸出過程處理的程序。比如我們最常見但是實際應用中很少的控制檯應用程序,它就是基於標準的I/O實現類的應用程序,接收命令行作爲輸入流,控制檯作爲標準輸出形式的應用程序。它的運行只需要有一個進程殼來構建輸入和輸出流即可。

而對於我們今天要詳細談的Web應用程序,其實它是起源於一種運行在操作系統上在組件程序,只不過它們的數據輸入輸出是基於網絡數據流的。

網絡基礎

從基礎的網絡知識我們知道,網絡上傳輸數據需要通過一個7層模型,也就是從最初的網絡硬件抽象定義到最高級的應用程序這個層級穿透而來。

要將兩臺物理的機器連接起來,我們需要對兩個機器進行標識命名,這些靠的是IP和端口,而網絡鏈路上傳輸的數據都是字節數據流,要知道這些數據流是沒有什麼具體格式的,但是到了網絡層時,我們必須要知道它來自哪裏要發給誰,所以我們需要對其進行一定的格式限制,這種抽象是通過電報格式定義來完成的。

比如我們需要定義發送的長度,標記爲,是否有順序等,這些字節流就被包裹成一個個數據報文,然後我們必須定義每個發送端和接收端之間的約定,就是告訴對方我發送的是什麼,你該如何接收它,比如多長是一個完整數據包,數據包的先後順序等,這些都是在我們知道了兩個通信店的IP地址以及如何連接也就是我們說的傳輸控制協議TCP的基礎上我們定義了更高級的應用協議,比如HTTP,FILE,MAIL等協議,當然最常見的協議就是HTTP協議了。

HTTP協議

它是在基礎的報文格式定義基礎上的一個更高級的抽象,它能告訴通信雙方我們通信的數據如何解析。就拿超文本傳輸協議來說吧,它規定了頭信息和內容信息,它還規定了處理這些信息的方法以及結果反饋代碼,這就是我們常說的GET,POST,DELETE,OPTIONS等,返回代碼比如從100,到500系列,當然這些已經進入到了應用協議部分。

我們所有的網絡應用程序都是基於點對點的通信的應用。也就是說要創建這樣的程序我們必須首先標識出能夠連接的兩個點,首先是主機名或者IP地址,然後就是我們要連接的具體應用,它一般會體現在哪個端口上或者端口下面的哪個路徑上。有了對等點的定義描述,我們就可以定義其控制傳輸的抽象,套接字概念。

編解碼問題

其實質上就是創建一個輸入輸出流的通道,網絡數據流都是通過Socket這個概念來定義和描述的。而我們編程,特別是Java的編程,我們只需要在我們應用程序所管理的空間中定義一個可以連接網絡Socket的通道,同時在內存中劃出一塊緩衝區,讓通道能夠有可操作的空間,然後利用不同緩衝區之間數據流動的過程對數據進行相應形式的變化,比如最基礎的是如何將網絡傳輸的字節流,轉變爲我們高級語言定義高級數據類型的過程,這個過程通常被稱爲解碼,同樣當我們需要將應用程序能夠理解的各種數據類型轉變爲可用通過網絡傳輸給其它地方的字節流時,這個過程被稱爲編碼。

因爲硬件能夠搞懂的目前就兩種狀態,這兩種狀態用數字表示就是二進制的0和1,所以我們使用的衆多高級編程語言裏,哪些複雜的數據類型都需要轉變成二進制的字節形式纔可以被CPU理解,被網絡硬件傳輸。因此我們的編程不可避免的就需要去完成這種編碼和解碼處理。當然隨着高級語言的不斷進化,各類常用的處理都已經變身爲各種語言標準的類庫或者功能包了,我們只需要拿來用即可。除非你想編寫自己的通信協議或者定義特殊的數據格式,否則對於編解碼來說一般不會涉及到。

瞭解了所有應用程序都是對數據流的處理這個基礎後,我們再來看Web應用程序,它是一種基於網絡的服務和獨立訪問結構的應用程序,也就是我們常說的Server-Client模式。

關於Servlet

這裏之所以定義出服務端和客戶端其實主要還是一個功能上的區分,但是底層實質上還是兩臺計算機的連接,通過字節流交換數據,通過協議來規定傳輸控制和數據解碼,而我們的web應用程序就是基於HTTP協議的網絡應用程序,因爲涉及到的網絡處理,所以技術人員將有關網絡處理部分獨立出來規定了很多規範,比如端點描述規範,數據傳輸格式規範,如何利用所在計算機操作系統環境的設置的規範等,這些反應到Java編程裏就是我們都熟悉的Servlet規範。

這個規範首先告訴我們基於Web的應用程序的基礎網絡部分需要在每臺聯網計算機上有一個角色來負責,我們稱這個角色爲容器,或者說是web服務器。

它就是要實現對計算機網絡的標識,連接,規定解析數據格式等工作,當然後來我們將其發展成綜合性的服務器,一邊要處理HTTP協議,一邊還可以通過一些接口更操作系統進行交互調用操作系統的功能組件來處理。比如網卡,文件的輸入輸出控制器等等。

我們可以簡單的描述一下一個Servlet容器的實現功能,首先它需要對運行自己的主機信息有一個抽象,能夠讓運行的程序瞭解它以及使用它可以使用的資源。

然後,它需要將基於網絡的字節流進行高級語言數據類型的轉換,比如將基於字節流解析成遵循HTTP協議的數據格式,HttpRequest,HttpResponse以及HttpServletRequest,HttpServletResponse等。

同時將對於宿主服務器環境參數抽象後引入到該容器中用於跟我們的應用程序交互。所以只要實現了Servlet的規範,就可以作爲操作系統和我們應用程序之間的媒介。

Servlet容器

市場上有許多成熟Servlet容器產品比如Tomcat,Jetty,Weblogic,Glassfish等。這裏面有很多輕量級的,只負責將輸入的網絡數據流轉換爲我們應用程序能夠理解和處理的數據形式,而這個過程都是通過創建輸入和輸出數據流的過程來完成的。有一些商業應用的實現附加的內容比較多,比如對系統環境資源的抽象繼承,比如數據庫連接資源,文件輸入輸出組件等。

我們開發的應用程序根據我們設計開發原則,我們首先將應用分解能功能組件,將每個功能組件設計成一個可以在容器中獨立運行的組件,該組件就是HttpServlet請求處理組件。

我們會根據請求的目標地址來標記各種功能,然後將這些唯一的目標地址和HTTP方法來標識運行的目標組件,而這個組件可以通過容器來計算機環境進行交互。

所以Servlet的頂層抽象就是一個service方法,該方法的輸入參數就是由容器進行封裝過的請求體和回覆體以及環境變量對象等。

當然我們會根據HTTP協議來具體的細化其支持的HTTP方法,所以我們可以來通過doGet,doPost等方法來完成具體的處理。

有了我們這樣一個基礎規範的功能實現,我們就有了一個可以包容和管理具體功能應用組件的容器,這個容器就是我們所說的web服務器。

如果你清楚了Servlet規範的本質就是對網絡數據流的封裝和編解碼處理,你可以自己動手從基礎的二進制數據流的封裝和編解碼轉換開始設計自己的web應用服務器。

也就是去實現點對點的通信處理,這裏說一下,目前的微服務架構的基礎就是對web服務器基礎網絡實現的重新分解設計。

Servlet 3.0 引入了反應流概念,就是通過接收方控制來管理大批量數據流的輸入輸出。

Spring框架和Web應用設計

瞭解了上面有關Web應用程序的結構後,我們再來看看Spring框架在web應用程序開發中扮演的角色是什麼。

我們知道Java企業級開發中有Java EE框架,其實就是基於Servlet容器來的,它只是將企業級應用開發的所有基礎功能都組件化了,比如容器化依賴注入,JPA等,當然必須有匹配的Web應用服務器來支持其運行。

同樣的Spring框架的核心部分就是組件容器,它的功能是通過更加有效更加輕量級的去組織和管理應用程序各功能組件。

其巧妙之處在於將整個組件設計成了一個Servlet組件實現,這就是Spring框架裏最爲核心的DispatchServlet,跟所有Servlet定義規範一樣,我們需要用一個請求的目標路徑來標識這個Servlet,然後讓Servlet容器在啓動時將它加載,並綁定到目標路徑上,以此在一個對根目錄請求的處理器中啓動一個應用程序組件管理容器,並將其處理器handler實現成一個前端控制模式,負責對其根目錄後的URL部分進行識別和匹配,以此來實現對Spring容器中負責處理後續URL資源的處理器的路由。

簡單說來,就是當外部訪問請求通過網絡到達Web服務器時,會將其根據Servlet規範和HTTP協議將其解碼成HttpServlet的請求和回覆數據結構類型,然後解析其訪問的目標資源URL,來匹配我們在Spring容器中註冊的用於處理它的組件和方法名稱,從而完成對該Servlet請求的處理。

由於現在我們開發應用程序時除了連續的文件上傳下載處理外,大多都是將二進制轉換爲JSON數據格式或者XML格式,如此我們只需要在Spring容器中註冊相應的處理組件即可。

總結

說到這裏想說的東西還沒說完,但是文章長度已經超出了預期,所以就此打住吧,只能在接下來另闢文章繼續講了。

本篇文章簡單的講了一下從Web應用程序的特點,以及能夠輔助Web應用程序運行的基礎容器服務規範,進而到了Spring框架的設計原則和結構實現設計。

這裏希望能夠帶大家從Web應用程序有別於其他類型的應用程序的特點開始,到支持Web應用程序運行的Servlet規範實現,在到Spring框架應用在Web應用程序時扮演的角色等內容過了一遍。接下來我會繼續沿着這個思路,講一下MVC模式,以及反應流處理模式等內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章