天天看點

為什麼要有 Servlet ,什麼是 Servlet 容器,什麼是 Web 容器?

以下代碼相信大家都很熟悉,大學時學 Java Web 都寫過這樣的代碼。

為什麼要有 Servlet ,什麼是 Servlet 容器,什麼是 Web 容器?

從第一次接觸 Servlet 到之後的很長一段時間内,我都沒了解 Servlet 是個什麼玩意?

為什麼要有 Servlet ?

為什麼要有 Servlet 容器?

啥又是 Web 容器、HTTP 伺服器?

今兒咱們就來盤盤,并且從中來看看架構和架構的設計套路。

看完之後可能對接口、抽象會有進一步的認識。

來,上車!

首先浏覽器發起 HTTP 請求,像早期的時候隻會請求一些靜态資源,這時候需要一個伺服器來處理 HTTP 請求,并且将相應的靜态資源傳回。

這個伺服器叫 HTTP 伺服器。

簡單點說就是解析請求,然後得知需要伺服器上面哪個檔案夾下哪個名字的靜态檔案,找到傳回即可。

為什麼要有 Servlet ,什麼是 Servlet 容器,什麼是 Web 容器?

而随着網際網路的發展,互動越發得重要,單純的靜态檔案滿足不了需求。

業務變得複雜,需要我們編寫代碼來處理諸多業務。

需要根據 HTTP 請求調用不同的業務邏輯來響應,但是我們的業務代碼不能跟 HTTP 伺服器耦合起來。

總不能在 HTTP 伺服器的具體實作裡面來做判斷到底需要調用哪個業務類吧?

這就把非業務和業務強相關了。

是以需要做一層抽象,将 HTTP 的解析和具體的業務隔離。

為什麼要有 Servlet ,什麼是 Servlet 容器,什麼是 Web 容器?

本質上的需求就是根據 HTTP 請求找到對應的業務實作類然後執行邏輯再傳回。

而業務千千萬,是以需要規定一個接口,是以業務類都實作這個接口這樣才好對接。

這就是接口的含義,就像 USB。

這個接口就是 Servlet,當然這是最狹義的解釋。

Servlet 其實是 Server Applet,全稱 Java Servlet,指的是用Java 編寫的服務端程式。

其實指代的是實作 Servlet 接口的那些業務類。

這就是 Servlet 的由來。

而 Servlet 容器其實就是用來管理和加載這些 Servlet 類的,根據 HTTP 請求找到對應的 Servlet 類這就是 Servlet 容器要做的事情。

看到這是不是覺得還能再抽一層?因為這好像也和具體的業務實作沒關系?

是的,還能抽一層。

沒必要把 Servlet 容器做的事情和具體的業務耦合起來,業務反正照着 Servlet 接口實作就行,這樣 Servlet 容器就可以加載它和管理它。

為什麼要有 Servlet ,什麼是 Servlet 容器,什麼是 Web 容器?

把請求和哪個 Servlet 對應關系也抽象出來,就是 web.xml 了,咱們在配置裡面告訴 Servlet 容器對應關系即可。

我圖中的業務實作其實對應的就是我們平常的 war 包,這就是業務和 Servlet 容器的解耦。

想必你也聽過 Servlet 規範,其實 Servlet 接口和 Servlet 容器這一整套包括目錄命名啊啥的合起來就叫 Servlet 規範。

所有相關的中間件按照 Servlet 規範實作,我們也按 Servlet 規範來實作業務代碼,這樣我們就能在不同場景選擇不同的 Web 中間件。

反正規範的目的就是為了對接友善,減少對接成本。

至此 HTTP 伺服器、Servlet 、Servlet 容器想必都清晰了。

而 Web 容器其實就是 HTTP 伺服器 + Servlet 容器,因為單單 Servlet 容器沒有解析 HTTP 請求、通信等相關功能。

是以把 Tomcat、Jetty 等實作包含了 HTTP 伺服器和 Servlet 容器的功能,稱之為 Web 容器。

從我們的分析一層一層的剝離,一層一層的抽象,相信你對 Web 有了更進一步的認識,我再畫個 Tomcat 的分析圖,應該就很清晰了。

從上面的一步步分析可以看出:其實架構的設計就是一系列相關的抽象。

先是抽象出 HTTP 服務,用來通信和解析協定。

再因為業務的複雜,為了不和 HTTP 服務耦合又抽象了一層 Servlet。

由 Servlet 加載和管理 Servlet ,來控制請求轉發到指定的 Servlet 實作類。

然後我們安心的開發業務即可。

因為抽象是以靈活易擴充,比如現在是 HTTP1.1 服務,可以換成 HTTP 2。

現在用 Tomcat 來作為 Servlet 容器,也可以換成 Jetty。

現在用原生的實作 Servlet 來做業務,也可以換成 SpringMVC。

随意變更,因為都抽象出來了,就很好替換,隻要遵循約定的接口實作即可。

看完了架構設計的套路,再說說架構套路。

接口和抽象類。

所有中間件設計必用的套路,當然我們自己的代碼也會這樣用。

先定義一個接口來約定一些動作,能做啥做啥。

然後再定義一個抽象類來實作這個接口,用來實作一些通用的邏輯,做到代碼的複用。

然後再搞一些常用的實作類繼承抽象類,友善開發者的使用。

剩下的就留給開發者自行擴充即可。

然後抽象類都會使用模闆方法,也就是定義執行的流程,具體實作邏輯由子類自行實作。

這就是必用的套路。

接口限制、抽象類代碼複用、實作常用實作類友善使用、剩下的自行擴充。

拿 Servlet 舉例,首先定義 Servlet 接口。

然後搞了個通用抽象類 GenericServlet,不過這個抽象類邏輯比較簡單。

然後搞了個常用的 HttpServlet 繼承了 GenericServlet。

套路就是這麼個套路,之後面試官問你接口和抽象類的問題,相信你也能答出來了。

套路大家應該都 GET 到了。

想必大家都聽過“計算機科學中的每個問題都可以用一間接層解決”。

是的,基本上所有問題抽象一層都能解決。

如果一層不夠,那就兩層。

文章來源于yes的練級攻略 ,作者是Yes呀

繼續閱讀