版权声明:转载请声明转自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。
Tomcat启动的时候,会调用ContextLoaderListener#contextInitialized方法创建一个RootAC。
- 当启动的时候先会初始化
-
- 当部署/第一次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