為什么要有 Servlet 卖漫,什么是 Servlet 容器,什么是 Web 容器赠群?

以下代碼相信大家都很熟悉羊始,大學(xué)時學(xué) Java Web 都寫過這樣的代碼。

從第一次接觸 Servlet 到之后的很長一段時間內(nèi)查描,我都沒理解 Servlet 是個什么玩意突委?

為什么要有 Servlet ?

為什么要有 Servlet 容器叹誉?

啥又是 Web 容器、HTTP 服務(wù)器闷旧?

今兒咱們就來盤盤长豁,并且從中來看看架構(gòu)和框架的設(shè)計(jì)套路。

看完之后可能對接口忙灼、抽象會有進(jìn)一步的認(rèn)識匠襟。

來,上車该园!

正文

首先瀏覽器發(fā)起 HTTP 請求酸舍,像早期的時候只會請求一些靜態(tài)資源,這時候需要一個服務(wù)器來處理 HTTP 請求里初,并且將相應(yīng)的靜態(tài)資源返回啃勉。

這個服務(wù)器叫 HTTP 服務(wù)器。

簡單點(diǎn)說就是解析請求双妨,然后得知需要服務(wù)器上面哪個文件夾下哪個名字的靜態(tài)文件淮阐,找到返回即可。

而隨著互聯(lián)網(wǎng)的發(fā)展刁品,交互越發(fā)得重要泣特,單純的靜態(tài)文件滿足不了需求。

業(yè)務(wù)變得復(fù)雜挑随,需要我們編寫代碼來處理諸多業(yè)務(wù)状您。

需要根據(jù) HTTP 請求調(diào)用不同的業(yè)務(wù)邏輯來響應(yīng),但是我們的業(yè)務(wù)代碼不能跟 HTTP 服務(wù)器耦合起來。

總不能在 HTTP 服務(wù)器的具體實(shí)現(xiàn)里面來做判斷到底需要調(diào)用哪個業(yè)務(wù)類吧膏孟?

這就把非業(yè)務(wù)和業(yè)務(wù)強(qiáng)相關(guān)了眯分。

所以需要做一層抽象,將 HTTP 的解析和具體的業(yè)務(wù)隔離骆莹。

本質(zhì)上的需求就是根據(jù) HTTP 請求找到對應(yīng)的業(yè)務(wù)實(shí)現(xiàn)類然后執(zhí)行邏輯再返回颗搂。

業(yè)務(wù)千千萬,所以需要規(guī)定一個接口幕垦,所以業(yè)務(wù)類都實(shí)現(xiàn)這個接口這樣才好對接丢氢。

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

這個接口就是 Servlet疚察,當(dāng)然這是最狹義的解釋。

Servlet 其實(shí)是 Server Applet仇奶,全稱 Java Servlet貌嫡,指的是用Java 編寫的服務(wù)端程序。

其實(shí)指代的是實(shí)現(xiàn) Servlet 接口的那些業(yè)務(wù)類该溯。

這就是 Servlet 的由來岛抄。

而 Servlet 容器其實(shí)就是管理和加載這些 Servlet 類的,拿到 HTTP 請求之后找到對應(yīng)的 Servlet 類這就是 Servlet 容器要做的事情狈茉。

看到這是不是覺得還能再抽一層夫椭?因?yàn)檫@好像也和具體的業(yè)務(wù)實(shí)現(xiàn)沒關(guān)系?

是的氯庆,還能抽一層蹭秋。

沒必要把 Servlet 容器做的事情和具體的業(yè)務(wù)耦合起來,業(yè)務(wù)反正照著 Servlet 接口實(shí)現(xiàn)就行堤撵,這樣 Servlet 容器就可以加載它和管理它仁讨。

把請求和哪個 Servlet 對應(yīng)關(guān)系也抽象出來,就是 web.xml 了实昨,咱們在配置里面告訴 Servlet 容器對應(yīng)關(guān)系即可洞豁。

我圖中的業(yè)務(wù)實(shí)現(xiàn)其實(shí)對應(yīng)的就是我們平常的 war 包,這就是業(yè)務(wù)和 Servlet 容器的解耦荒给。

想必你也聽過 Servlet 規(guī)范族跛,其實(shí) Servlet 接口和 Servlet 容器這一整套包括目錄命名啊啥的合起來就叫 Servlet 規(guī)范。

所有相關(guān)的中間件按照 Servlet 規(guī)范實(shí)現(xiàn)锐墙,我們也按 Servlet 規(guī)范來實(shí)現(xiàn)業(yè)務(wù)代碼礁哄,這樣我們就能在不同場景選擇不同的 Web 中間件。

反正規(guī)范的目的就是為了對接方便溪北,減少對接成本桐绒。

至此 HTTP 服務(wù)器夺脾、Servlet 、Servlet 容器想必都清晰了茉继。

而 Web 容器其實(shí)就是 HTTP 服務(wù)器 + Servlet 容器咧叭,因?yàn)閱螁?Servlet 容器沒有解析 HTTP 請求、通信等相關(guān)功能烁竭。

所以把 Tomcat菲茬、Jetty 等實(shí)現(xiàn)包含了 HTTP 服務(wù)器和 Servlet 容器的功能,稱之為 Web 容器派撕。

從我們的分析一層一層的剝離婉弹,一層一層的抽象,相信你對 Web 有了更進(jìn)一步的認(rèn)識终吼,我再畫個 Tomcat 的分析圖镀赌,應(yīng)該就很清晰了。

從上面的一步步分析可以看出:其實(shí)架構(gòu)的設(shè)計(jì)就是一系列相關(guān)的抽象际跪。

先是抽象出 HTTP 服務(wù)商佛,用來通信和解析協(xié)議。

再因?yàn)闃I(yè)務(wù)的復(fù)雜姆打,為了不和 HTTP 服務(wù)耦合又抽象了一層 Servlet良姆。

由 Servlet 加載和管理 Servlet ,來控制請求轉(zhuǎn)發(fā)到指定的 Servlet 實(shí)現(xiàn)類幔戏。

然后我們安心的開發(fā)業(yè)務(wù)即可玛追。

因?yàn)槌橄笏造`活易擴(kuò)展,比如現(xiàn)在是 HTTP1.1 服務(wù)评抚,可以換成 HTTP 2豹缀。

現(xiàn)在用 Tomcat 來作為 Servlet 容器伯复,也可以換成 Jetty慨代。

現(xiàn)在用原生的實(shí)現(xiàn) Servlet 來做業(yè)務(wù),也可以換成 SpringMVC啸如。

隨意變更侍匙,因?yàn)槎汲橄蟪鰜砹耍秃芎锰鎿Q叮雳,只要遵循約定的接口實(shí)現(xiàn)即可想暗。

框架設(shè)計(jì)的一個套路

看完了架構(gòu)設(shè)計(jì)的套路,再說說框架套路帘不。

接口和抽象類说莫。

所有中間件設(shè)計(jì)必用的套路,當(dāng)然我們自己的代碼也會這樣用寞焙。

定義一個接口來約定一些動作储狭,能做啥做啥互婿。

然后再定義一個抽象類來實(shí)現(xiàn)這個接口,用來實(shí)現(xiàn)一些通用的邏輯辽狈,做到代碼的復(fù)用慈参。

然后再搞一些常用的實(shí)現(xiàn)類繼承抽象類,方便開發(fā)者的使用刮萌。

剩下的就留給開發(fā)者自行擴(kuò)展即可驮配。

然后抽象類都會使用模板方法,也就是定義執(zhí)行的流程着茸,具體實(shí)現(xiàn)邏輯由子類自行實(shí)現(xiàn)壮锻。

這就是必用的套路。

接口約束元扔、抽象類代碼復(fù)用躯保、實(shí)現(xiàn)常用實(shí)現(xiàn)類方便使用、剩下的自行擴(kuò)展澎语。

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

public interface Servlet {
    void init(ServletConfig config) throws ServletException;
    ServletConfig getServletConfig();
    void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;
    String getServletInfo();
    void destroy();
}

然后搞了個通用抽象類 GenericServlet擅羞,不過這個抽象類邏輯比較簡單尸变。

public abstract class GenericServlet implements Servlet, ServletConfig,
        java.io.Serializable {
  ................省略一些.............
   @Override
    public ServletConfig getServletConfig() {
        return config;
    }
    @Override
    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
................省略一些.....................
}

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

public abstract class HttpServlet extends GenericServlet {

    private static final long serialVersionUID = 1L;

    private static final String METHOD_DELETE = "DELETE";
    private static final String METHOD_HEAD = "HEAD";
    private static final String METHOD_GET = "GET";
  ....................
}

套路就是這么個套路减俏,之后面試官問你接口和抽象類的問題召烂,相信你也能答出來了。

最后

套路大家應(yīng)該都 GET 到了娃承。

想必大家都聽過“計(jì)算機(jī)科學(xué)中的每個問題都可以用一間接層解決”奏夫。

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

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

歡迎加我好友進(jìn)行深入地交流梳猪,備注「進(jìn)群」麻削,拉你進(jìn)交流&內(nèi)推群。

平日的面試題遇到難處春弥,或者看某個知識點(diǎn)翻遍全網(wǎng)的資料還是感覺很模糊呛哟、不透徹,可以私聊我匿沛,給我留言扫责。

遇到合適的我會整理寫出一篇文章,我不會的去請教別人也給整出來逃呼。

那種工作遇到很細(xì)節(jié)的場景的還是別了鳖孤,這種問你上司比較合適:)

巨人的肩膀

《深入拆解Tomcat & Jetty》 李號雙


我是 yes借帘,從一點(diǎn)點(diǎn)到億點(diǎn)點(diǎn),歡迎在看淌铐、轉(zhuǎn)發(fā)肺然、留言,我們下篇見腿准。

更多文章可以看我 Github 的個人文章匯總:https://github.com/yessimida/yes 歡迎 star !

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末际起,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吐葱,更是在濱河造成了極大的恐慌粘我,老刑警劉巖咙崎,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼠冕,死亡現(xiàn)場離奇詭異悠抹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)孟辑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門哎甲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人饲嗽,你說我怎么就攤上這事炭玫。” “怎么了貌虾?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵吞加,是天一觀的道長。 經(jīng)常有香客問我尽狠,道長衔憨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任袄膏,我火速辦了婚禮践图,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哩陕。我一直安慰自己平项,他們只是感情好赫舒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布悍及。 她就那樣靜靜地躺著,像睡著了一般接癌。 火紅的嫁衣襯著肌膚如雪心赶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天缺猛,我揣著相機(jī)與錄音缨叫,去河邊找鬼椭符。 笑死,一個胖子當(dāng)著我的面吹牛耻姥,可吹牛的內(nèi)容都是我干的销钝。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼琐簇,長吁一口氣:“原來是場噩夢啊……” “哼蒸健!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婉商,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤似忧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丈秩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盯捌,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年蘑秽,在試婚紗的時候發(fā)現(xiàn)自己被綠了饺著。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡肠牲,死狀恐怖瓶籽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情埂材,我是刑警寧澤塑顺,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站俏险,受9級特大地震影響严拒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜竖独,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一裤唠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧莹痢,春花似錦种蘸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坦辟,卻和暖如春刊侯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锉走。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工滨彻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留藕届,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓亭饵,卻偏偏與公主長得像休偶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子辜羊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容