相對於spring boot咱們使用spring mvc更加頻繁和熟悉。sprint boot具備spring mvc的功能,二者之間到底存在着什麼樣的關係,經過下面的篇幅咱們一塊兒來分析。web
咱們再回顧下spring mvc的配置,首先看下web.xml:spring
能夠看到該文件中配置了context-param、listener以及servlet信息
(執行順序:context-param -> listener -> filter -> servlet)
spring-servlet.xml是應用初始化容器所使用的配置。segmentfault
ContextLoaderListener:在啓動Web容器時,自動裝配Spring applicationContext.xml的配置信息,本質上是建立了一個WebApplicationContext,也就是建立了spring ioc容器,固然也能夠不配置該listener,也就沒法使用其ioc提供的功能;正常狀況下,都會配置。mvc
ContextLoadListener結構以下:app
ContextLoaderListener實現了ServletContextListener,咱們應該很熟悉了,有兩個方法spa
contextInitialized(ServletContextEvent sce):All ServletContextListeners are notified of context initialization before any filter or servlet in the web application is initialized.
即全部ServletContextListeners的該方法都會在filter和servlet初始化以前調用。線程
contextDestroyed (ServletContextEvent sce):All servlets and filters have been destroy()ed before any ServletContextListeners are notified of context destruction.
即全部ServletContextListeners的該方法都會在filter和servlet銷燬以前調用。3d
參數均爲ServletContextEvent,能夠獲取ServletContext對象。code
同時ContextLoaderListener繼承自ContextLoader,監聽器的核心功能都在此類中。
在ContextLoaderListener的contextInitialized方法中調用了父類ContextLoader的
initWebApplicationContext(ServletContext servletContext)方法,該方法的主要就是建立了一個IOC容器即WebApplicationContext,並將IOC容器存到servletContext中。xml
執行流程以下:
createWebApplicationContext(servletContext)
1).determineContextClass決定使用什麼類型的容器
先去web.xml中獲取contextClass配置,獲取到了就用配置的容器,若是沒有指定IOC容器類型,默認爲XmlWebApplicationContext。
默認容器在spring-web的jar包中的配置文件ContextLoader.properties中配置:
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext。
2).((ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass))
建立IOC容器
loadParentContext(servletContext)
加載web.xml中的父容器信息,若是有則設置。父容器是不可以引用子容器中的bean,子類能夠引用父容器中的bean,各個自容器中的bean互不可見。
configureAndRefreshWebApplicationContext
a.獲取contextConfigLocation配置(applicationContext.xml)做爲初始化容器的圖紙,Spring工廠進行Bean生產、依賴關係注入(裝配)及Bean實例分發都依賴於它。
b.獲取ApplicationContextInitializer的實現類
ApplicationContextInitializer:主要目的就是在ConfigurableApplicationContext類型(或者子類型)的ApplicationContext作refresh以前,容許咱們對ConfigurableApplicationContext的實例作進一步的設置或者處理。
能夠在web.xml中經過以下配置設置param-name
globalInitializerClasses:表明全部的web application都會應用或
contextInitializerClasses:表明只有當前的web application會使用
配置以下:
<context-param> <param-name>contextInitializerClasses</param-name> <param-value>com.my.MyApplicationContextInitializer</param-value> </context-param>
全部實現類會在此處實例化並依次執行initialize方法。
將該IOC容器放到servletContext中
將當前線程類加載器和IOC容器作關聯,以便於後續獲取IOC容器
Java的線程上下文類加載器請見文章 類加載器相關
上述過程當中所涉及到的接口及類圖以下:
ApplicationContext:context的頂層類,ApplicationContext繼承了BeanFactory,這也說明了 Spring 容器中運行的主體對象是 Bean,另外 ApplicationContext 繼承了 ResourceLoader 接口,使得 ApplicationContext能夠訪問到任何外部資源。
ConfigurableApplicationContext:ConfigurableApplicationContext接口中定義了一些基本操做,好比設置上下文ID,設置父應用上下文,添加監聽器和刷新容器相關的操做等。
ConfigurableWebApplicationContext:是web應用上下文使用的接口,主要是設置servletContext和servletConfig。
AbstractApplicationContext:實現refresh方法,構建Bean關係網,構建容器的核心方法。
至此:springmvc啓動過程當中第一大部分構建IOC容器部分結束