Spring MVC-ContextLoaderListener和DispatcherServlet

Tomcat or Jetty as the Servlet container will build a ServletContext for each Web application to store all Servlet, Filter, Listener. When Spring MVC starts, it mainly involves DispatcherServlet and ContextLoaderListener.

About ContextLoaderListener and DispatcherServlet
ContextLoaderListener
  1. ContextLoaderListener will start as a Listener first, and create a WebApplicationContext to load all beans except for Web components such as Controller. This ApplicationContext exists as the root container. For the entire Web application, there can only be one, that is, the parent container, which will be Shared by all sub-containers, sub-containers can access beans in the parent container, but not vice versa.
  2. A. The ContextLoaderListener will be created directly under the XML configuration, and then the WebApplicationContext will be initialized in the contextInitialized method.
    B. If AnnotationConfig is used, obtain a WebApplicationContext through AnnotationConfigWebApplicationContext and pass it to ContextLoadListener.
    Then call the initWebApplicationContext of the parent class ContextLoader in the contextInitialized method to initialize.

    public class ContextLoader {
      /**
      * The root WebApplicationContext instance that this loader manages.
      */
     private WebApplicationContext context;
    
     public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
      this.context = createWebApplicationContext(servletContext);
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
      return this.context;
     }
    }

    It can be seen that ContextLoader, as the parent class of ContextLoaderListener, after creating WebApplicationContext (for XML configuration, using the configuration file specified by the contextConfigLocation parameter), will save ApplicationContext to ServletContext through the attribute WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, and ContextLoader is creating WebApplicationContext It will also check whether this attribute has an associated object before, ensuring that there is only one root WebApplicationContext in the entire Servletcontext.

DispatcherServlet
  1. After the Listener and Filter are loaded, the DispatcherServlet is likely to be initialized as the only Servlet in the ServletContext, and forwards requests as the Front Controller of the entire Web application.
  2. A. XML configuration, the default DispatcherServlet is generated, and the WebApplicationContext is created through the configuration file specified by the contextConfigLocation in the init-param during init.
    B.AnnotationConfig, generate WebApplicationContext after reading JavaConfig through AnnotationConfigWebApplicationContext, and pass it to DispatcherServlet for construction.
  3. After the DispatcherServlet is constructed, the init method is called to initialize, and the parent container of the WebApplicationContext associated with the DispatcherServlet is set to the WebApplicationContext created by the ContextLoaderListener.
  4. The WebApplicationContext associated with DispatcherServlet will be exposed to handlers and subsequent web components with the attribute set to request when the request arrives.

It can be seen that for a web application built with SpringMVC, although ContextLoaderListener can only load one root container, it is actually optional, and DispatcherServlet is the core of request forwarding processing and returning results is indispensable, and it can be used without only.
However, it is recommended to use this layered container structure in Web applications, which is clearer and facilitates subsequent expansion.

web.xml and Servlet3.0

The traditional web.xml configuration is suitable for servlet containers before the Servlet3 specification, while the servlet containers after Servlet3 can be configured using annotations or Java code.
In the Servlet3.0 environment, the container will look for the implementation class of the ServletContainerInitializer interface in the classpath to configure the Servlet container. Spring's SpringServletContainerInitializer class implements this interface, and will look for the implementation class of the WebApplicationInitializer interface to complete the loading of the above two components.

public interface WebApplicationInitializer {
    /**
     * Configure the given {@link ServletContext} with any servlets, filters, listeners
     * context-params and attributes necessary for initializing this web application. See
     * examples {@linkplain WebApplicationInitializer above}.
     * @param servletContext the {@code ServletContext} to initialize
     * @throws ServletException if any call against the given {@code ServletContext}
     * throws a {@code ServletException}
     */
    void onStartup(ServletContext servletContext) throws ServletException;
}

The two main implementation base classes of this interface are AbstractContextLoaderInitializer and AbstractDispatcherServletInitializer, which are respectively responsible for loading ContextLoaderListener and DispatcherServlet into ServletContext, but the functions of these two classes to obtain WebApplicationContext respectively are not implemented. If necessary, you can implement it by yourself. XML gets the WebApplicationContext, and Spring provides an AbstractAnnotationConfigDispatcherServletInitializer for you to inherit. As the name suggests, it uses JavaConfig to load the WebApplicationContext.
Of course, you can also implement WebApplicationInitializer yourself to manually load Servlet and Listener such as ServletContext.
Emphasis: The Servlet3.0 container will check the class that implements ServletContainerInitializer in the classpath, and use the onStartup function of this interface to initialize the ServletContext. If this does not apply, then use the traditional web.xml for the assembly of ContextLoaderListener and DispatcherServlet.

emphasize

The configuration of DispatcherServlet and ContextLoaderListener is divided into two types: web.xml and Servlet container discovery, and the configuration of WebApplicationContext for these two components is also divided into XML mode and JavaConfig mode.

  1. web.xml + application.xml =

    <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>classpath*:config/spring-context.xml</param-value>
    </context-param>
    //<br/>
    <servlet>
       <servlet-name>ebook-manage</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:config/spring-servlet.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
       <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
         <servlet-name>ebook-manage</servlet-name>
         <url-pattern>/</url-pattern>
    </servlet-mapping>
  2. web.xml + JavaConfig =

    <context-param>
    <param-name>contextClass</param-name>
    <param-value>
    org.springframework.web.context.support.
    ➥ AnnotationConfigWebApplicationContext
    </param-value>
    </context-param>
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.habuma.spitter.config.RootConfig</param-value>
    </context-param>
    <listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListener
    </listener-class>
    </listener>
    <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
    <param-name>contextClass</param-name>
    <param-value>
    org.springframework.web.context.support.
    ➥ AnnotationConfigWebApplicationContext
    </param-value>
    </init-param>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    com.habuma.spitter.config.WebConfigConfig
    </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>
  3. ServletContainerInitializer(WebApplicationInitializer) + JavaConfig =
    public class SpittrWebAppInitializer
    extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {
    return new String[] { "/" };
    }
    @Override
    protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] { RootConfig.class };
    }
    @Override
    protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[] { WebConfig.class };
    }
    }
  4. ServletContainerInitializer(WebApplicationInitializer) + application.xml =
    Need to inherit AbstractDispatcherServletInitializer and then implement the function of loading ApplicationContext through application.xml.

http://www.jianshu.com/p/9d77e49852c6

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326564843&siteId=291194637