zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    我大学时代的好朋友要结婚了!
    (function(root,factory){})(this,function($){}) 一个立即执行的匿名函数自调
    非书面的非官方的常见的HTTP请求状态码分析
    一个页面多个HTTP请求 页面卡顿!
    requestAnimationFrame Web中写动画的另一种选择
    js 点击 返回顶部 动画
    css3动画 一行字鼠标触发 hover 从左到右颜色渐变
    var 和 let 的异同?
    H5案例分享:使用JS判断客户端、浏览器、操作系统类型
    基于浏览器的HTML5地理定位
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873128.html
Copyright © 2011-2022 走看看