相对于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容器部分结束