SpringMVC啟動(dòng)過程詳解

本文學(xué)習(xí)自阿里大牛RunforLove银舱,很完美的講解文章,原文:[RunforLove]
(http://www.cnblogs.com/RunForLove/p/5688731.html)

極力推薦的spring源碼解讀Qデ臁P灾谩矮锈!

通過對(duì)SpringMVC啟動(dòng)過程的深入研究繁疤,期望掌握J(rèn)ava Web容器啟動(dòng)過程;掌握SpringMVC啟動(dòng)過程揣炕;了解SpringMVC的配置文件如何配置趁舀,為什么要這樣配置;掌握SpringMVC是如何工作的祝沸;掌握Spring源碼的設(shè)計(jì)和增強(qiáng)閱讀源碼的技巧矮烹。
目錄
1.Web容器初始化過程
2.SpringMVC中web.xml配置
3.認(rèn)識(shí)ServletContextListener
4.認(rèn)識(shí)ContextLoaderListener
5.DispatcherServlet初始化(HttpServletBean ? FrameworkServlet ? DispatcherServlet
6.ContextLoaderListener與DispatcherServlet關(guān)系
7.DispatcherServlet的設(shè)計(jì)
8.DispatcherServlet工作原理

一、Web容器初始化過程


上圖展示了web容器初始化的過程罩锐,其官方文檔給出了這樣的描述:
  When a web application is deployed into a container, the following steps must be performed, in this order, before the web application begins processing client requests.
Instantiate an instance of each event listener identified by a <listener> element in the deployment descriptor.
For instantiated listener instances that implement ServletContextListener, call the contextInitialized() method.
Instantiate an instance of each filter identified by a <filter> element in the deployment descriptor and call each filter instance's init() method.
Instantiate an instance of each servlet identified by a <servlet> element that includes a <load-on-startup> element in the order defined by the load-on-startup element values, and call each servlet instance's init() method.

二奉狈、SpringMVC中web.xml的配置


上圖是截取的web.xml中的配置,在<listener>標(biāo)簽中定義了spring容器加載器涩惑;在<servlet>標(biāo)簽中定義了spring前端控制器仁期。

上圖是源碼中接口ServletContextListener的定義,可以看到在其注釋中指明:servlet和Filter初始化前和銷毀后竭恬,都會(huì)給實(shí)現(xiàn)了servletContextListener接口的監(jiān)聽器發(fā)出相應(yīng)的通知跛蛋。

上面是類ContextLoadListener的定義,它實(shí)現(xiàn)了上面的servletContextListener痊硕。這里用到了代理模式赊级,簡(jiǎn)單的代理了ContextLoader類。ContextLoadListener類用來創(chuàng)建Spring application context岔绸,并且將application context注冊(cè)到servletContext里面去理逊。

結(jié)合上面的WEB容器啟動(dòng)的過程,以及接口ServletContextListener和類ContextLoadListener盒揉。我們知道:
  在 Servlet API中有一個(gè)ServletContextListener接口晋被,它能夠監(jiān)聽ServletContext對(duì)象的生命周期,實(shí)際上就是監(jiān)聽Web應(yīng)用的生命周期刚盈。當(dāng)Servlet容器啟動(dòng)或終止Web應(yīng)用時(shí)羡洛,會(huì)觸發(fā)ServletContextEvent事件,該事件由ServletContextListener來處理藕漱。在ServletContextListener接口中定義了處理ServletContextEvent 事件的兩個(gè)方法contextInitialized()和contextDestroyed()欲侮。
  ContextLoaderListener監(jiān)聽器的作用就是啟動(dòng)Web容器時(shí),自動(dòng)裝配ApplicationContext的配置信息谴分。因?yàn)樗鼘?shí)現(xiàn)了ServletContextListener這個(gè)接口锈麸,在web.xml配置了這個(gè)監(jiān)聽器,啟動(dòng)容器時(shí)牺蹄,就會(huì)默認(rèn)執(zhí)行它實(shí)現(xiàn)的方法忘伞。由于在ContextLoaderListener中關(guān)聯(lián)了ContextLoader這個(gè)類,所以整個(gè)加載配置過程由ContextLoader來完成。

上面是initWebApplicationContext的過程氓奈,方法名稱即是其含義翘魄。方法中首先創(chuàng)建了WebApplicationContext,配置并且刷新實(shí)例化整個(gè)SpringApplicationContext中的Bean舀奶。因此暑竟,如果我們的Bean配置出錯(cuò)的話,在容器啟動(dòng)的時(shí)候育勺,會(huì)拋異常出來的但荤。
  綜上,ContextLoaderListener類起著至關(guān)重要的作用涧至。它讀取web.xml中配置的context-param中的配置文件腹躁,提前在web容器初始化前準(zhǔn)備業(yè)務(wù)對(duì)應(yīng)的Application context;將創(chuàng)建好的Application context放置于ServletContext中,為springMVC部分的初始化做好準(zhǔn)備南蓬。
三纺非、DispatchServlet初始化
  在SpringMVC架構(gòu)中,DispatchServlet負(fù)責(zé)請(qǐng)求分發(fā)赘方,起到控制器的作用烧颖。下面詳細(xì)來解釋說明:

DispatchServlet名如其義,它的本質(zhì)上是一個(gè)Servlet窄陡。從上面圖可以看到炕淮,下層的子類不斷的對(duì)HttpServlet父類進(jìn)行方法擴(kuò)展。

上圖是抽象類HttpServletBean的實(shí)現(xiàn)泳梆,我們知道HttpServlet有兩大核心方法:init()和service()方法鳖悠。HttpServletBean重寫了init()方法,在這部分优妙,我們可以看到其實(shí)現(xiàn)思路:公共的部分統(tǒng)一來實(shí)現(xiàn),變化的部分統(tǒng)一來抽象憎账,交給其子類來實(shí)現(xiàn)套硼,故用了abstract class來修飾類名。此外胞皱,HttpServletBean提供了一個(gè)HttpServlet的抽象實(shí)現(xiàn)邪意,使的Servlet不再關(guān)心init-param部分的賦值,讓servlet更關(guān)注于自身Bean初始化的實(shí)現(xiàn)反砌。


上圖是FrameworkServlet的官方定義雾鬼, 它提供了整合web javabean和spring application context的整合方案。那么它是如何實(shí)現(xiàn)的呢宴树?在源碼中我們可以看到通過執(zhí)行initWebApplicationContext()方法和initFrameworkServlet()方法實(shí)現(xiàn)策菜。


DispatchServlet是HTTP請(qǐng)求的中央調(diào)度處理器,它將web請(qǐng)求轉(zhuǎn)發(fā)給controller層處理,它提供了敏捷的映射和異常處理機(jī)制又憨。DispatchServlet轉(zhuǎn)發(fā)請(qǐng)求的核心代碼在doService()方法中實(shí)現(xiàn)翠霍,詳細(xì)代碼參照?qǐng)D上。

上圖是DispatchServlet類和ContextLoaderListener類的關(guān)系圖蠢莺。首先寒匙,用ContextLoaderListener初始化上下文,接著使用DispatchServlet來初始化WebMVC的上下文躏将。

上圖是DispatchServlet的工作流程圖锄弱,作為HTTP請(qǐng)求的中央控制器,它在SpringMVC中起著分發(fā)請(qǐng)求的作用祸憋。下面總結(jié)了DispatchServlet設(shè)計(jì)的一些特點(diǎn)總結(jié)棵癣。

四、請(qǐng)求流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夺衍,一起剝皮案震驚了整個(gè)濱河市狈谊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沟沙,老刑警劉巖河劝,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異矛紫,居然都是意外死亡赎瞎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門颊咬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來务甥,“玉大人,你說我怎么就攤上這事喳篇〕伲” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵麸澜,是天一觀的道長(zhǎng)挺尿。 經(jīng)常有香客問我,道長(zhǎng)炊邦,這世上最難降的妖魔是什么编矾? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮馁害,結(jié)果婚禮上窄俏,老公的妹妹穿的比我還像新娘。我一直安慰自己碘菜,他們只是感情好凹蜈,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布限寞。 她就那樣靜靜地躺著,像睡著了一般踪区。 火紅的嫁衣襯著肌膚如雪昆烁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天缎岗,我揣著相機(jī)與錄音静尼,去河邊找鬼。 笑死传泊,一個(gè)胖子當(dāng)著我的面吹牛鼠渺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眷细,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼拦盹,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了溪椎?” 一聲冷哼從身側(cè)響起普舆,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎校读,沒想到半個(gè)月后沼侣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歉秫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年蛾洛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雁芙。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轧膘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出兔甘,到底是詐尸還是另有隱情谎碍,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布裂明,位于F島的核電站椿浓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏闽晦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一提岔、第九天 我趴在偏房一處隱蔽的房頂上張望仙蛉。 院中可真熱鬧,春花似錦碱蒙、人聲如沸荠瘪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)哀墓。三九已至趁餐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間篮绰,已是汗流浹背后雷。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吠各,地道東北人臀突。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像贾漏,于是被迫代替她去往敵國(guó)和親候学。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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