相对于spring boot我们使用spring mvc更加频繁和熟悉。sprint boot具有spring mvc的功能,两者之间到底存在着什么样的关系,通过下面的篇幅我们一起来分析。
我们再回顾下spring mvc的配置,首先看下web.xml:
可以看到该文件中配置了context-param、listener以及servlet信息
(执行顺序:context-param -> listener -> filter -> servlet)
spring-servlet.xml是应用初始化容器所使用的配置。
ContextLoaderListener:在启动Web容器时,自动装配Spring applicationContext.xml的配置信息,本质上是创建了一个WebApplicationContext,也就是创建了spring ioc容器,当然也可以不配置该listener,也就无法使用其ioc提供的功能;正常情况下,都会配置。
ContextLoadListener结构如下:
ContextLoaderListener实现了ServletContextListener,我们应该很熟悉了,有两个方法
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销毁之前调用。
参数均为ServletContextEvent,可以获取ServletContext对象。
同时ContextLoaderListener继承自ContextLoader,监听器的核心功能都在此类中。
在ContextLoaderListener的contextInitialized方法中调用了父类ContextLoader的
initWebApplicationContext(ServletContext servletContext)方法,该方法的主要就是创建了一个IOC容器即WebApplicationContext,并将IOC容器存到servletContext中。
执行流程如下:
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容器部分结束
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。