自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解Java開發(fā)Web應(yīng)用程序的底層原理

開發(fā) 后端
前面一篇文章,我從整個應(yīng)用程序的整體以及跟運行環(huán)境的關(guān)系簡單聊了一下我們現(xiàn)在常用的Spring框架的設(shè)計基礎(chǔ)和原則,其中主要是控制反轉(zhuǎn)和依賴注入,以及容器化編程等概念。

[[285627]]

前言

前面一篇文章,我從整個應(yīng)用程序的整體以及跟運行環(huán)境的關(guān)系簡單聊了一下我們現(xiàn)在常用的Spring框架的設(shè)計基礎(chǔ)和原則,其中主要是控制反轉(zhuǎn)和依賴注入,以及容器化編程等概念。

這里我不想去復(fù)述這些概念的定義,因為那些東西網(wǎng)上隨便都能百度到,我想通過我的描述將這些概念串聯(lián)起來,讓大家更好的去立即它們知道為什么要這樣去做,我們每天開發(fā)使用的框架到底是個什么東西,它的設(shè)計思想以及規(guī)范的由來。做到知其然還知其所以然,能夠讓我們在開發(fā)過程中更好的去使用它們,面對問題知道它大概的解決方向。

本文我想繼續(xù)沿著前面的思路來談?wù)劵赪eb的應(yīng)用程序需要使用Spring框架的容器化管理開發(fā)相關(guān)的理解。

Web應(yīng)用程序與Servlet規(guī)范

當(dāng)然說起應(yīng)用程序開發(fā)來,我們都熟悉,現(xiàn)在應(yīng)用程序有很多種分類,最初的控制臺程序,服務(wù)組件程序,到桌面應(yīng)用程序,到基于HTTP訪問協(xié)議的web應(yīng)程序等。

其實它們的本質(zhì)就是基于某種輸入/輸出過程處理的程序。比如我們最常見但是實際應(yīng)用中很少的控制臺應(yīng)用程序,它就是基于標(biāo)準(zhǔn)的I/O實現(xiàn)類的應(yīng)用程序,接收命令行作為輸入流,控制臺作為標(biāo)準(zhǔn)輸出形式的應(yīng)用程序。它的運行只需要有一個進(jìn)程殼來構(gòu)建輸入和輸出流即可。

而對于我們今天要詳細(xì)談的Web應(yīng)用程序,其實它是起源于一種運行在操作系統(tǒng)上在組件程序,只不過它們的數(shù)據(jù)輸入輸出是基于網(wǎng)絡(luò)數(shù)據(jù)流的。

 

網(wǎng)絡(luò)基礎(chǔ)

從基礎(chǔ)的網(wǎng)絡(luò)知識我們知道,網(wǎng)絡(luò)上傳輸數(shù)據(jù)需要通過一個7層模型,也就是從最初的網(wǎng)絡(luò)硬件抽象定義到最高級的應(yīng)用程序這個層級穿透而來。

要將兩臺物理的機器連接起來,我們需要對兩個機器進(jìn)行標(biāo)識命名,這些靠的是IP和端口,而網(wǎng)絡(luò)鏈路上傳輸?shù)臄?shù)據(jù)都是字節(jié)數(shù)據(jù)流,要知道這些數(shù)據(jù)流是沒有什么具體格式的,但是到了網(wǎng)絡(luò)層時,我們必須要知道它來自哪里要發(fā)給誰,所以我們需要對其進(jìn)行一定的格式限制,這種抽象是通過電報格式定義來完成的。

比如我們需要定義發(fā)送的長度,標(biāo)記為,是否有順序等,這些字節(jié)流就被包裹成一個個數(shù)據(jù)報文,然后我們必須定義每個發(fā)送端和接收端之間的約定,就是告訴對方我發(fā)送的是什么,你該如何接收它,比如多長是一個完整數(shù)據(jù)包,數(shù)據(jù)包的先后順序等,這些都是在我們知道了兩個通信店的IP地址以及如何連接也就是我們說的傳輸控制協(xié)議TCP的基礎(chǔ)上我們定義了更高級的應(yīng)用協(xié)議,比如HTTP,F(xiàn)ILE,MAIL等協(xié)議,當(dāng)然最常見的協(xié)議就是HTTP協(xié)議了。

HTTP協(xié)議

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

我們所有的網(wǎng)絡(luò)應(yīng)用程序都是基于點對點的通信的應(yīng)用。也就是說要創(chuàng)建這樣的程序我們必須首先標(biāo)識出能夠連接的兩個點,首先是主機名或者IP地址,然后就是我們要連接的具體應(yīng)用,它一般會體現(xiàn)在哪個端口上或者端口下面的哪個路徑上。有了對等點的定義描述,我們就可以定義其控制傳輸?shù)某橄?,套接字概念?/p>

 

編解碼問題

其實質(zhì)上就是創(chuàng)建一個輸入輸出流的通道,網(wǎng)絡(luò)數(shù)據(jù)流都是通過Socket這個概念來定義和描述的。而我們編程,特別是Java的編程,我們只需要在我們應(yīng)用程序所管理的空間中定義一個可以連接網(wǎng)絡(luò)Socket的通道,同時在內(nèi)存中劃出一塊緩沖區(qū),讓通道能夠有可操作的空間,然后利用不同緩沖區(qū)之間數(shù)據(jù)流動的過程對數(shù)據(jù)進(jìn)行相應(yīng)形式的變化,比如最基礎(chǔ)的是如何將網(wǎng)絡(luò)傳輸?shù)淖止?jié)流,轉(zhuǎn)變?yōu)槲覀兏呒壵Z言定義高級數(shù)據(jù)類型的過程,這個過程通常被稱為解碼,同樣當(dāng)我們需要將應(yīng)用程序能夠理解的各種數(shù)據(jù)類型轉(zhuǎn)變?yōu)榭捎猛ㄟ^網(wǎng)絡(luò)傳輸給其它地方的字節(jié)流時,這個過程被稱為編碼。

因為硬件能夠搞懂的目前就兩種狀態(tài),這兩種狀態(tài)用數(shù)字表示就是二進(jìn)制的0和1,所以我們使用的眾多高級編程語言里,哪些復(fù)雜的數(shù)據(jù)類型都需要轉(zhuǎn)變成二進(jìn)制的字節(jié)形式才可以被CPU理解,被網(wǎng)絡(luò)硬件傳輸。因此我們的編程不可避免的就需要去完成這種編碼和解碼處理。當(dāng)然隨著高級語言的不斷進(jìn)化,各類常用的處理都已經(jīng)變身為各種語言標(biāo)準(zhǔn)的類庫或者功能包了,我們只需要拿來用即可。除非你想編寫自己的通信協(xié)議或者定義特殊的數(shù)據(jù)格式,否則對于編解碼來說一般不會涉及到。

了解了所有應(yīng)用程序都是對數(shù)據(jù)流的處理這個基礎(chǔ)后,我們再來看Web應(yīng)用程序,它是一種基于網(wǎng)絡(luò)的服務(wù)和獨立訪問結(jié)構(gòu)的應(yīng)用程序,也就是我們常說的Server-Client模式。

關(guān)于Servlet

這里之所以定義出服務(wù)端和客戶端其實主要還是一個功能上的區(qū)分,但是底層實質(zhì)上還是兩臺計算機的連接,通過字節(jié)流交換數(shù)據(jù),通過協(xié)議來規(guī)定傳輸控制和數(shù)據(jù)解碼,而我們的web應(yīng)用程序就是基于HTTP協(xié)議的網(wǎng)絡(luò)應(yīng)用程序,因為涉及到的網(wǎng)絡(luò)處理,所以技術(shù)人員將有關(guān)網(wǎng)絡(luò)處理部分獨立出來規(guī)定了很多規(guī)范,比如端點描述規(guī)范,數(shù)據(jù)傳輸格式規(guī)范,如何利用所在計算機操作系統(tǒng)環(huán)境的設(shè)置的規(guī)范等,這些反應(yīng)到Java編程里就是我們都熟悉的Servlet規(guī)范。

這個規(guī)范首先告訴我們基于Web的應(yīng)用程序的基礎(chǔ)網(wǎng)絡(luò)部分需要在每臺聯(lián)網(wǎng)計算機上有一個角色來負(fù)責(zé),我們稱這個角色為容器,或者說是web服務(wù)器。

它就是要實現(xiàn)對計算機網(wǎng)絡(luò)的標(biāo)識,連接,規(guī)定解析數(shù)據(jù)格式等工作,當(dāng)然后來我們將其發(fā)展成綜合性的服務(wù)器,一邊要處理HTTP協(xié)議,一邊還可以通過一些接口更操作系統(tǒng)進(jìn)行交互調(diào)用操作系統(tǒng)的功能組件來處理。比如網(wǎng)卡,文件的輸入輸出控制器等等。

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

然后,它需要將基于網(wǎng)絡(luò)的字節(jié)流進(jìn)行高級語言數(shù)據(jù)類型的轉(zhuǎn)換,比如將基于字節(jié)流解析成遵循HTTP協(xié)議的數(shù)據(jù)格式,HttpRequest,HttpResponse以及HttpServletRequest,HttpServletResponse等。

同時將對于宿主服務(wù)器環(huán)境參數(shù)抽象后引入到該容器中用于跟我們的應(yīng)用程序交互。所以只要實現(xiàn)了Servlet的規(guī)范,就可以作為操作系統(tǒng)和我們應(yīng)用程序之間的媒介。

 

Servlet容器

市場上有許多成熟Servlet容器產(chǎn)品比如Tomcat,Jetty,Weblogic,Glassfish等。這里面有很多輕量級的,只負(fù)責(zé)將輸入的網(wǎng)絡(luò)數(shù)據(jù)流轉(zhuǎn)換為我們應(yīng)用程序能夠理解和處理的數(shù)據(jù)形式,而這個過程都是通過創(chuàng)建輸入和輸出數(shù)據(jù)流的過程來完成的。有一些商業(yè)應(yīng)用的實現(xiàn)附加的內(nèi)容比較多,比如對系統(tǒng)環(huán)境資源的抽象繼承,比如數(shù)據(jù)庫連接資源,文件輸入輸出組件等。

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

我們會根據(jù)請求的目標(biāo)地址來標(biāo)記各種功能,然后將這些唯一的目標(biāo)地址和HTTP方法來標(biāo)識運行的目標(biāo)組件,而這個組件可以通過容器來計算機環(huán)境進(jìn)行交互。

所以Servlet的頂層抽象就是一個service方法,該方法的輸入?yún)?shù)就是由容器進(jìn)行封裝過的請求體和回復(fù)體以及環(huán)境變量對象等。

當(dāng)然我們會根據(jù)HTTP協(xié)議來具體的細(xì)化其支持的HTTP方法,所以我們可以來通過doGet,doPost等方法來完成具體的處理。

有了我們這樣一個基礎(chǔ)規(guī)范的功能實現(xiàn),我們就有了一個可以包容和管理具體功能應(yīng)用組件的容器,這個容器就是我們所說的web服務(wù)器。

如果你清楚了Servlet規(guī)范的本質(zhì)就是對網(wǎng)絡(luò)數(shù)據(jù)流的封裝和編解碼處理,你可以自己動手從基礎(chǔ)的二進(jìn)制數(shù)據(jù)流的封裝和編解碼轉(zhuǎn)換開始設(shè)計自己的web應(yīng)用服務(wù)器。

也就是去實現(xiàn)點對點的通信處理,這里說一下,目前的微服務(wù)架構(gòu)的基礎(chǔ)就是對web服務(wù)器基礎(chǔ)網(wǎng)絡(luò)實現(xiàn)的重新分解設(shè)計。

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

 

Spring框架和Web應(yīng)用設(shè)計

了解了上面有關(guān)Web應(yīng)用程序的結(jié)構(gòu)后,我們再來看看Spring框架在web應(yīng)用程序開發(fā)中扮演的角色是什么。

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

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

其巧妙之處在于將整個組件設(shè)計成了一個Servlet組件實現(xiàn),這就是Spring框架里最為核心的DispatchServlet,跟所有Servlet定義規(guī)范一樣,我們需要用一個請求的目標(biāo)路徑來標(biāo)識這個Servlet,然后讓Servlet容器在啟動時將它加載,并綁定到目標(biāo)路徑上,以此在一個對根目錄請求的處理器中啟動一個應(yīng)用程序組件管理容器,并將其處理器handler實現(xiàn)成一個前端控制模式,負(fù)責(zé)對其根目錄后的URL部分進(jìn)行識別和匹配,以此來實現(xiàn)對Spring容器中負(fù)責(zé)處理后續(xù)URL資源的處理器的路由。

簡單說來,就是當(dāng)外部訪問請求通過網(wǎng)絡(luò)到達(dá)Web服務(wù)器時,會將其根據(jù)Servlet規(guī)范和HTTP協(xié)議將其解碼成HttpServlet的請求和回復(fù)數(shù)據(jù)結(jié)構(gòu)類型,然后解析其訪問的目標(biāo)資源URL,來匹配我們在Spring容器中注冊的用于處理它的組件和方法名稱,從而完成對該Servlet請求的處理。

由于現(xiàn)在我們開發(fā)應(yīng)用程序時除了連續(xù)的文件上傳下載處理外,大多都是將二進(jìn)制轉(zhuǎn)換為JSON數(shù)據(jù)格式或者XML格式,如此我們只需要在Spring容器中注冊相應(yīng)的處理組件即可。

總結(jié)

說到這里想說的東西還沒說完,但是文章長度已經(jīng)超出了預(yù)期,所以就此打住吧,只能在接下來另辟文章繼續(xù)講了。

本篇文章簡單的講了一下從Web應(yīng)用程序的特點,以及能夠輔助Web應(yīng)用程序運行的基礎(chǔ)容器服務(wù)規(guī)范,進(jìn)而到了Spring框架的設(shè)計原則和結(jié)構(gòu)實現(xiàn)設(shè)計。

這里希望能夠帶大家從Web應(yīng)用程序有別于其他類型的應(yīng)用程序的特點開始,到支持Web應(yīng)用程序運行的Servlet規(guī)范實現(xiàn),在到Spring框架應(yīng)用在Web應(yīng)用程序時扮演的角色等內(nèi)容過了一遍。接下來我會繼續(xù)沿著這個思路,講一下MVC模式,以及反應(yīng)流處理模式等內(nèi)容。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2013-08-08 09:48:10

Web

2009-09-22 12:22:54

ibmdwLotus

2013-11-19 15:35:01

2011-07-26 09:41:23

iPhone xcode Mac OS X

2010-12-31 15:29:54

Web應(yīng)用程序

2009-04-01 14:33:33

2009-07-09 16:47:26

Servlet的Web

2011-05-24 10:30:31

PythonNetBeans ID

2011-05-06 15:31:28

moblweb開發(fā)DSL

2010-05-20 09:48:36

2011-03-22 14:12:17

LAMP

2012-02-21 22:01:24

Windows 8Web開發(fā)

2012-03-15 15:35:51

iUI框架EclipseiOS Web

2011-06-01 13:20:29

ipad平板電腦移動開發(fā)

2022-12-25 18:03:13

Debug原理軟件

2009-02-27 17:00:25

2012-04-19 09:34:21

ibmdw

2009-01-16 09:22:40

Web應(yīng)用程序Web程序管理Web服務(wù)

2015-01-06 09:59:59

云應(yīng)用程序Java開發(fā)SQL

2011-11-29 16:07:36

移動Web開發(fā)框架移動開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號