[Spring MVC Research] Register 9 special components in Spring MVC to the DispatcherServlet attribute.

Article directory

  • 0. Brief description of the working principle of Spring MVC
  • 1. 9 special components in Spring MVC
  • 2. Registration principles of 9 components
  • 3. Questions about Spring MVC registration components
  • 3. Reference

Background: Spring MVC is an MVC framework and an implementation of the Servlet specification. The Servlet specification defines many components, which have two major branches that are closely related to daily development:

  • Servlet branch
  • Filter branch

This article discusses Servlet components. The core Servlet in Spring MVC is DispatcherServlet. There are and only 9 special components initialized in DispatcherServlet. Note that there are and only.

Note: You may hear beans such as “welcome page” and “static resources” in Spring Boot. Many of them are actually “assembled into these 9 special components”

0. Brief description of the working principle of Spring MVC

Brief description of principle:

1. Whether it is MVC or Spring Boot, beans are registered in the container;

2. After the container is started, it will guide the initialization of DispatcherServlet. During initialization, the relevant beans will be set to the properties of DispatcherServlet;

3. Finally, the browser’s request is processed through various attribute beans in DispatcherServlet.

Detailed reference:

1. 9 special components in Spring MVC

DispatcherServlet delegates to special beans to handle requests and render appropriate responses. By “special beans”, we refer to object instances managed by spring that implement the WebFlux framework contract. They usually come with built-in contracts, but you can customize their properties, extend or replace them

The following table lists some common special beans:

Bean type Description
HandlerMapping Maps a request to a handler (handler also contains a series of pre- and post-interceptors). Mapping is implemented based on various HandlerMapping interfaces.
HandlerAdapter The main purpose of HandlerAdapter is to protect DispatcherServlet from these details
HandlerExceptionResolver HandlerExceptionResolver
ViewResolver View resolver (if it is a front-end and back-end separation project, ignore this part directly)
LocaleResolver, LocaleContextResolver
ThemeResolver
MultipartResolver File upload parsing
FlashMapManager

2. Registration principle of 9 components

  • Because DispatcherServlet is also a Servlet, according to the Servlet specification, the Servlet’s public void init(ServletConfig config) throws ServletException; will be called. Finally, the initialization of DispatcherServlet will be called and the following code will be loaded.

The following code is used to initialize the 9 special beans of DispatcherServlet.

// Responsible for initializing each of the above components
protected void initStrategies(ApplicationContext context) {<!-- -->
    initMultipartResolver(context);
    initLocaleResolver(context); //
    initThemeResolver(context);
    initHandlerMappings(context);//
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    initViewResolvers(context);
    initFlashMapManager(context);
}
  • Initialization of the above 9 components, except MultipartResolver, other components will load the default configuration from DispatcherServlet.properties if the user does not customize them

MultipartResolver is too special and is not configured by default, which means that Spring MVC does not support “file upload” by default.

  • DispatcherServlet.properties file content
# Exactly 8 components (except without MultipartResolver)
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
org.springframework.web.servlet.function.support.RouterFunctionMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
org.springframework.web.servlet.function.support.HandlerFunctionAdapter


org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashM

3. Questions about Spring MVC registration components

In the protected void initStrategies(ApplicationContext context) method of DispatcherServlet. Special components of Spring MVC are registered, but for several List type components, Spring’s sorting rules AnnotationAwareOrderComparator are used when customizing, while loading from DispatcherServlet.properties The configuration does not apply sorting rules.Should we think that Spring does not provide a unified sorting method?

Take the initHandlerMappings() method as an example:

private void initHandlerMappings(ApplicationContext context) {<!-- -->
    this.handlerMappings = null;
 
        Map<String, HandlerMapping> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
        if (!matchingBeans.isEmpty()) {<!-- -->
            this.handlerMappings = new ArrayList<>(matchingBeans.values());
            // <1> Sorting rules are applied to beans obtained from the container
            AnnotationAwareOrderComparator.sort(this.handlerMappings);
        }
 
 
    if (this.handlerMappings == null) {<!-- -->
        // <2> No collation applied for configuration loaded from DispatcherServlet.properties
        this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
        if (logger.isTraceEnabled()) {<!-- -->
            logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
                         "': using default strategies from DispatcherServlet.properties");
        }
    }
}

3. Reference

Official website: https://docs.spring.io/spring-framework/docs/5.0.6.RELEASE/spring-framework-reference/web.html#mvc-servlet-special-bean-types