javascript
SpringMVC的启动过程
前言
下面是一個(gè)SpringMVC應(yīng)用的配置文件,需要注意兩個(gè)地方,一個(gè)是ContextLoaderListener,一個(gè)是dispatcherServlet。web容器正是通過這兩個(gè)配置才和spring管理起來。ContextLoaderListener與web容器的ServletContext關(guān)聯(lián),為Spring的IOC容器提供了一個(gè)宿主環(huán)境。在建立起IOC容器體系之后,把DispatcherServlet作為SpringMVC處理web請(qǐng)求的轉(zhuǎn)發(fā)器建立起來,完成響應(yīng)http請(qǐng)求的準(zhǔn)備。
SpringMVC啟動(dòng)過程大致分為兩個(gè)階段:
第一階段.ContextLoaderListener初始化,實(shí)例化IOC容器,并將此容器注冊(cè)到ServletContext中。
第二階段DispatcherServlet初始化,建立自己的上下文,也注冊(cè)到ServletContext中。
?
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><display-name>ota</display-name><description>ota web application</description><!-- 系統(tǒng)組件加載順序:context-param -> listener -> filter -> servlet --><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><!-- GZip --><filter><filter-name>gzipFilter</filter-name><filter-class>com.travelsky.ibeplus.compress.Compress2WayFilter</filter-class></filter><filter-mapping><filter-name>gzipFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- Servlet that dispatches request to registered handlers (Controller implementations). --><servlet><servlet-name>ota</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/mvc-core-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!-- 需要定義在對(duì)應(yīng)的servlet之后 --><servlet-mapping><servlet-name>ota</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>1、Spring IOC容器的啟動(dòng)
Spring IOC容器的啟動(dòng)在我博客中這一篇博文“Spring是怎樣啟動(dòng)的” 有詳細(xì)介紹,這里再簡(jiǎn)單概述下。
ContextLoaderListener實(shí)現(xiàn)ServletContextListener,這個(gè)接口里面的方法會(huì)結(jié)合web容器的生命周期被調(diào)用。因?yàn)镾ervletContextListener是ServletContext的監(jiān)聽者,如果ServletContext發(fā)生變化,會(huì)觸發(fā)相應(yīng)的事件,而監(jiān)聽者一直對(duì)這些事件進(jìn)行監(jiān)聽,如果接受到了監(jiān)聽的事件,就會(huì)作于相應(yīng)處理。例如在服務(wù)器啟動(dòng),ServletContext被創(chuàng)建的時(shí)候,ServletContextListener的contextInitialized()方法被調(diào)用,從而拉開了初始化Spring IOC容器的序幕
2、DispatcherServlet的啟動(dòng)? (HttpServletBean *? FrameworkServlet * DispatcherServlet)
DispatchServlet本質(zhì)上是一個(gè)Servlet,web容器啟動(dòng)的時(shí)候,servlet也會(huì)初始化,其init方法被調(diào)用,開啟初始化之旅。
DispatchServlet會(huì)建立自己的上下文來持有Spring MVC特殊的bean對(duì)象,在建立這個(gè)自己持有的Ioc容器的時(shí)候,會(huì)從ServletContext中得到根上下文作為DispatchServlet上下文的parent上下文。有了這個(gè)根上下文,再對(duì)自己持有的上下文進(jìn)行初始化,最后把自己持有的這個(gè)上下文保存到ServletContext中,供以后檢索和使用。
下面來詳細(xì)解釋下:
- DispatchServlet名如其義,它的本質(zhì)上是一個(gè)Servlet,子類不斷的對(duì)HttpServlet父類進(jìn)行方法擴(kuò)展
- 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的整合方案。在源碼中可以看到通過執(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)
2.1 HttpServletBean
?
?上圖是抽象類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)。
2.2 FrameworkServlet
?在HttpServletBean中有一方法initServletBean()需要子類去實(shí)現(xiàn),因此 FrameworkServlet需要實(shí)現(xiàn)initServletBean()方法
2.3 DispatcherServlet
在FrameworkServlet中有一方法onRefresh()需要子類去實(shí)現(xiàn),因此DispatcherServlet需要去實(shí)現(xiàn)onRefresh()方法。
另外一些MVC的特性初始化時(shí)在initStrategies()中實(shí)現(xiàn)的,包括支持國(guó)際化的LocalResolver、支持Request映射的HandlerMappings,以及視圖生成的ViewResolver等等。
比如初始化HandlerMappings,在SpringMVC中,HandlerMappings的作用是為Http請(qǐng)求找到對(duì)應(yīng)的Controller控制器,來進(jìn)一步處理請(qǐng)求。
?注意:
在web.xml配置文件中,DispatcherServlet中有一配置<load-on-startup>1</load-on-startup>,表示在容器啟動(dòng)的時(shí)候就加載該servlet。
當(dāng)<load-on-startup>值為0或者大于0時(shí),表示容器在應(yīng)用啟動(dòng)時(shí)就加載這個(gè)servlet(實(shí)例化并調(diào)用其init()方法)。
當(dāng)是一個(gè)負(fù)數(shù)時(shí)或者沒有指定時(shí),則表示第一次請(qǐng)求該servlet才加載。
正數(shù)的值越小,啟動(dòng)該servlet的優(yōu)先級(jí)越高。
3.?DispatcherServlet類和ContextLoaderListener類的關(guān)系圖:
小結(jié):首先,用ContextLoaderListener初始化上下文,接著使用DispatchServlet來初始化WebMVC的上下文。
?
轉(zhuǎn)載于:https://www.cnblogs.com/whx7762/p/7762665.html
總結(jié)
以上是生活随笔為你收集整理的SpringMVC的启动过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Session.run() Tenso
- 下一篇: Github Pages建立个人博客