SpringMVC中的RootWebApplicationContext与ServletWebApplicationContext

版权声明:转载请声明转自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中DispatcherServletcontextConfigLocation定义扫描Controller的配置文件。

servletContext和两个配置文件的关系如下:

servletContext>contextLoaderListener->Root ApplicationContext->Spring
servletContext>dispacherServlet->Servlet WebAppContext->SpringMVC

两者关系

ServletAC中含有RootAC

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

原文地址:https://www.cnblogs.com/thewindkee/p/12873128.html