Spring MVC深入學(xué)習(xí)之啟動(dòng)初始化過(guò)程
前言
雖然從學(xué)java的第一個(gè)程序——helloworld至今,已經(jīng)有好幾個(gè)年頭了。當(dāng)時(shí)自己找資料,看視頻,學(xué)習(xí)了java的輸入輸出流,多線程,網(wǎng)絡(luò)編程等等, 而三大框架(Struts、Hibernate、Spring)基本只是開(kāi)了個(gè)頭就出來(lái)實(shí)習(xí)了,尤其對(duì)于Spring更是沒(méi)有進(jìn)行系統(tǒng)的學(xué)習(xí), 雖然在實(shí)習(xí)的時(shí)候通過(guò)看項(xiàng)目,基本明白了spring mvc編程的框架是怎么回事,遇到需求知道如何寫(xiě)代碼,在哪寫(xiě)代碼,但是還是缺乏一個(gè)系統(tǒng)的認(rèn)識(shí)。
因?yàn)樽罱卷?xiàng)目使用 struts2 作為控制層框架,為了實(shí)現(xiàn)前后端分離,計(jì)劃將 struts2 切換為 SpringMVC ,因此,這段時(shí)間都在學(xué)習(xí)新的框架,《Spring實(shí)戰(zhàn)》是一本好書(shū),里面對(duì) Spring 的原理實(shí)現(xiàn)以及應(yīng)用都說(shuō)得很透徹,強(qiáng)烈推薦,但是如果想深挖 Spring 的實(shí)現(xiàn),還是要從他的源碼入手,這次,就先從 SpringMVC 初始化開(kāi)始。
- Web 容器初始化過(guò)程
- SpringMVC的Web.xml配置
- DispatchServlet初始化
Web容器初始化過(guò)程
web容器初始化的過(guò)程,其官方文檔給出了這樣的描述:
- 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.
其初始化的過(guò)程實(shí)際如下:

SpringMVC 的 web.xml配置
web.xml 配置代碼:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- <listener>標(biāo)簽中定義了spring容器加載器
- <servlet>標(biāo)簽中定義了spring前端控制器
在 Servlet API中有一個(gè)ServletContextListener接口,它能夠監(jiān)聽(tīng)ServletContext對(duì)象的生命周期,實(shí)際上就是監(jiān)聽(tīng)Web應(yīng)用的生命周期。當(dāng)Servlet容器啟動(dòng)或終止Web應(yīng)用時(shí),會(huì)觸發(fā)ServletContextEvent事件,該事件由ServletContextListener來(lái)處理。在ServletContextListener接口中定義了處理ServletContextEvent 事件的兩個(gè)方法contextInitialized()和contextDestroyed() 。
ContextLoaderListener監(jiān)聽(tīng)器的作用就是啟動(dòng)Web容器時(shí),自動(dòng)裝配ApplicationContext的配置信息。因?yàn)樗鼘?shí)現(xiàn)了ServletContextListener這個(gè)接口,在web.xml配置了這個(gè)監(jiān)聽(tīng)器,啟動(dòng)容器時(shí),就會(huì)默認(rèn)執(zhí)行它實(shí)現(xiàn)的方法。由于在ContextLoaderListener中關(guān)聯(lián)了ContextLoader這個(gè)類(lèi),所以整個(gè)加載配置過(guò)程由ContextLoader來(lái)完成。
DispatchServlet初始化
在SpringMVC架構(gòu)中,DispatchServlet負(fù)責(zé)請(qǐng)求分發(fā),起到控制器的作用。下面詳細(xì)來(lái)解釋說(shuō)明:

- DispatchServlet名如其義,它的本質(zhì)上是一個(gè)Servlet,子類(lèi)不斷的對(duì)HttpServlet父類(lèi)進(jìn)行方法擴(kuò)展
- HttpServlet有兩大核心方法:init()和service()方法。HttpServletBean重寫(xiě)了
init()方法,在這部分,我們可以看到其實(shí)現(xiàn)思路:公共的部分統(tǒng)一來(lái)實(shí)現(xiàn),變化的部分統(tǒng)一來(lái)抽象,交給其子類(lèi)來(lái)實(shí)現(xiàn),故用了abstract class來(lái)修飾類(lèi)名。此外,HttpServletBean提供了一個(gè)HttpServlet的抽象實(shí)現(xiàn),使的Servlet不再關(guān)心init-param部分的賦值,讓servlet更關(guān)注于自身Bean初始化的實(shí)現(xiàn) - FrameworkServlet提供了整合web javabean和spring application context的整合方案。在源碼中可以看到通過(guò)執(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)
DispatchServlet類(lèi)和ContextLoaderListener類(lèi)的關(guān)系圖:

用ContextLoaderListener初始化上下文,接著使用DispatchServlet來(lái)初始化WebMVC的上下文
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Java實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
淺談JAVA 線程狀態(tài)中可能存在的一些誤區(qū)
這篇文章主要介紹了淺談JAVA 線程狀態(tài)中可能存在的一些誤區(qū),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Java使用Jedis操作Redis服務(wù)器的實(shí)例代碼
本篇文章主要介紹了Java使用Jedis操作Redis服務(wù)器的實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
SpringBoot如何進(jìn)行業(yè)務(wù)校驗(yàn)實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于SpringBoot如何進(jìn)行業(yè)務(wù)校驗(yàn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01
SpringCloud集成Hystrix熔斷過(guò)程分步分解
通過(guò)hystrix可以解決雪崩效應(yīng)問(wèn)題,它提供了資源隔離、降級(jí)機(jī)制、融斷、緩存等功能。接下來(lái)通過(guò)本文給大家分享SpringCloud集成Hystrix熔斷,感興趣的朋友一起看看吧2022-09-09
Java中FTPClient上傳中文目錄、中文文件名亂碼問(wèn)題解決方法
這篇文章主要介紹了Java中FTPClient上傳中文目錄、中文文件名亂碼問(wèn)題解決方法,本文使用apache-commons-net工具包時(shí)遇到這個(gè)問(wèn)題,解決方法很簡(jiǎn)單,需要的朋友可以參考下2015-05-05
Kotlin 基礎(chǔ)教程之?dāng)?shù)組容器
這篇文章主要介紹了Kotlin 基礎(chǔ)教程之?dāng)?shù)組容器的相關(guān)資料,需要的朋友可以參考下2017-06-06

