版权声明:转载请声明转自http://blog.csdn.net/thewindkee https://blog.csdn.net/thewindkee/article/details/95483639
文章目录
RootWebApplicationContext以下简称RootAC
ServletWebApplicationContext以下简称ServletAC
简介
Web on Servlet Stack 1.1.1. Context Hierarchy中描述到了SpringMVC中两个WebApplicationContext的继承关系。RootAC会被注入到ServletAC的parentBeanFactory中。

典型的SpringMVC中web.xml配置
<web-app>
<display-name>spring-web</display-name>
<context-param>
<!--spring相关-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatch</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--springMVC相关-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatch-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatch</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
通常,
在web.xml中context-param的使用contextConfigLocation定义一个配置扫描Spring的service和dao的配置文件。ContextLoaderListener,ContextLoaderListener本质是一个ServletContextListener,在创建ServletContext的时候会去加载这些配置文件, 这些配置文件可以看做Spring相关的配置。(如果这里扫描了SpringMVC相关的配置,某些bean被加载多次)
ServletContextListener监听ServletContext。当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法;
在web.xml中DispatcherServlet的contextConfigLocation定义扫描Controller的配置文件。
servletContext和两个配置文件的关系如下:
servletContext>contextLoaderListener->Root ApplicationContext->Spring
servletContext>dispacherServlet->Servlet WebAppContext->SpringMVC
两者关系
ServletAC中含有RootAC

parentBeanFactory中含有RootAC

从parentBeanFactory中获取bean
用当无法找到对应的bean则从parentBeanFactory中查找

如果不配置ContextListener和对应contextConfigLocation,这里RootAC也是null,ServletAC的parent是null

代码中获取RootWebApplicationContext与ServletWebApplicationContext
推荐使用RequestContextUtils.findWebApplicationContext(request);获取ServletWebApplicationContext,该applicationContext包含SpringMVC与Spring配置的bean。
WebApplicationContext servletApplicationContext = RequestContextUtils.findWebApplicationContext(request);//推荐,ServletAC包含RootAC
WebApplicationContext rootApplicationContext = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());//RootAC
Root WebApplicationContext

Servlet WebApplicationContext

★什么时候将RootAC注入到ServletAC中的?
-
- 当启动的时候先会初始化
ContextLoaderListener对应的RootAC。(TODO)
- 当启动的时候先会初始化
-
- 当部署/第一次HTTP访问的时候会将初始化ServletAC,并将RootAC注入其中。
为什么要问Servlet的初始化时间
如果load-on-startup设置为>=0, 部署的时候就会调用。 如果多个servlet的load-on-startup设置的值一样,由容器自己确定这几个servlet的初始化顺序。
如果load-on-startup没有设置,或者为负数,那么由容器自行决定,通常是在第一次Request请求时调用的,而且在doSerivce之前只调用一次
DispatcherServlet本质是一个HttpServletBean继承HttpServlet

那么当一次过来的时候 由于我们配置的<url-pattern>/*</url-pattern>将所有的请求交给DispacherServlet处理。
调用链
httpServletBean.init->initServletBean->initWebApplicationContext->createWebApplicationContext(root)->wac.refresh()

将RootAC传入,准备创建ServletAC

设置ServletAC的contextConfigLocation,并调用wac.setParent将RootAC注入到ServletAC。
注意看 这里的 configLocation 是我们指定的xml文件

refresh启动ApplicationContext
refresh->finishRefresh的时候会publishEvent(new ContextRefreshedEvent(this))触发ContextRefreshListener();//初始化handlerMapping等

refresh-SpringIOC源码学习总结
Web on Servlet Stack 1.1.1. Context Hierarchy
《看透SpringMVC》第9章 创建SpringMVC之器
本文发布于2019年7月11日16:26:28