Search code examples
springspring-mvchierarchyapplicationcontext

SpringMVC ApplicationContext Hierarchy


web.xml fragment:

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext-security.xml</param-value>
  </context-param>

  <!-- Processes application requests -->
  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

According to this answer:

2- The DispatcherServlet context becomes a child of the root context. ...

My question is to understand how Spring makes this decision (to attach the DispatcherServlet context to the root context). There's nothing explicit in either appContext XML file to specify this, and AFAICT there's nothing you can specify in the XML to make this association explicitly.

When the DispatcherServlet is instantiating its appContext, how does it know to call setParent() on it (SpringMVC works just fine without a root appContext), and if there's more than one non-child appContext already in existence how would it choose?


Solution

  • DispatcherServlet extends FrameworkServlet, which has the following code:

        protected WebApplicationContext initWebApplicationContext() {
            WebApplicationContext rootContext =
                    WebApplicationContextUtils.getWebApplicationContext(getServletContext());
                WebApplicationContext wac = null;
    

    which is subsequently used as:

     wac = createWebApplicationContext(rootContext);
    

    WebApplicationContextUtils retrieve the context as:

    public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
        return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    }
    
    public static WebApplicationContext getWebApplicationContext(ServletContext sc, String attrName) {
        Assert.notNull(sc, "ServletContext must not be null");
        Object attr = sc.getAttribute(attrName);
                ...
        return (WebApplicationContext) attr;
    }
    

    In a nutshell: root context stores a reference to itself in a context attribute. All FrameworkServlets will try to retrieve said context attribute and bind themselves to the retrieved root context (if defined).