Springboot provides automatic configuration for SpringMVC, which works well for most applications.

These auto-configurations extend the Spring default Settings and can be referenced in the official SpringBoot documentation.

Document link:Docs. Spring. IO/spring – the boot…

The following is an excerpt from the official documentation that explains in great detail what pringBoot auto-installs for SpringMVC, which features it extends, and how to use the extended features:

// Automatic configuration adds the following functionality to Spring's default Settings:
The auto-configuration adds the following features on top of Spring’s defaults:

// Include the view parser
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
    
// Supports static resource folder paths, as well as Webjars
Support for serving static resources, including support for WebJars 
    
// Registers Converter automatically. This is what happens when a webpage submits data to an object, such as converting a "1" string to an int
// Formatter: for example, if the page gives us a 2019-8-10, it will automatically format us as a Date object
Automatic registration of Converter, GenericConverter, and Formatter beans.
    
// HttpMessageConverters
// SpringMVC is used to convert Http requests and responses. For example, we want to convert a User object to a JSON string;
Support for HttpMessageConverters (covered later in this document).
    
// Define error code generation rules
Automatic registration of MessageCodesResolver (covered later in this document).
    
// Home page customization
Static index.html support.
    
// Icon customization
Custom Favicon support (covered later in this document).
    
// Initialize the data binder to help us wrap the request data into a JavaBean!
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
    
    

    
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = extended MVC function = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/* If you want to keep The Spring Boot MVC functionality and want to add other MVC configurations (interceptors, formatters, view controllers, and more), you can add your own @Configuration class of type WebMvcConfiguer, But do not add @enableWebMVC. If you want to provide the RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver instances of custom, You can WebMVCregistrationAdapter instance declaration to provide such components. * /
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration 
(interceptors, formatters, view controllers, and other features). you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.// If you want full control over Spring MVC, you can add your own @Configuration annotated with @enableWebMVC.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
Copy the code

1, ContentNegotiatingViewResolver configuration principle

Previously in SpringMVC, we had to manually configure the view parser in the ApplicationContext. XML file in the Resources directory, as shown below:

<! -- View parser -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      id="internalResourceViewResolver">
    <! -- prefix -- -- >
    <property name="prefix" value="/WEB-INF/jsp/" />
    <! - the suffix - >
    <property name="suffix" value=".jsp" />
</bean>
Copy the code

But, in the springboot has helped for springmvc automatic assembly ContentNegotiatingViewResolver class, ContentNegotiatingViewResolver parser is commonly used in Spring MVC view a view of the parser.

ContentNegotiatingViewResolver class source code is as follows:

public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
      implements ViewResolver.Ordered.InitializingBean {
// a class that implements a ViewResolver is considered a ViewResolver
Copy the code

ContentNegotiatingViewResolver rewrite ViewResolver interface method, the source code is as follows:

What is the actual implementation of getting candidate views? Click to continue to analyze the source:

So:

Write configuration classes to implement the view parser manually

package com.cheng.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

// Extend the springMVC configuration
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    // Inject into Spring
    @Bean
    public ViewResolver myViewResolver(a){
        return new MyViewResolver();
    }

    // create a custom ViewResolver. Any class that implements a ViewResolver can be considered a ViewResolver
    public static class MyViewResolver implements ViewResolver{

        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null; }}}Copy the code

To see if our custom view resolver is working, just make a breakpoint in the doDisoatch method of the DispatcherServlet class, launch the SpringBoot program, visit any page, and debug

Find that our custom view parser is working

Conclusion:

  • ContentNegotiatingViewResolver the parser is used to combine all the views of the parser, it will return to the most appropriate view parser, so ContentNagotiatingViewResolver oneself does not parse the view, Instead, delegate to other view parsers.

  • If we want to customize something, we just write the component and give it to SpringBoot, and springBoot will auto-assemble it for us!

2. Configure the format converter

Configure the Formatter format converter

Formatter configuration in application.properties:

@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.mvc.format.date")
public String getDateFormat(a) {
   return this.format.getDate();
}
Copy the code

Testing:

Date =dd/MM/ YYYY # Custom date format spring.mVc.format. Date = dD-MM-YYYYCopy the code

When SpringBoot automatically configures many components, it first checks whether the container has user-configured components (if the user configures @bean). If so, it uses user-configured components, and if not, it uses auto-configured components.

If there are some components that can have more than one, such as our view parser, combine the user’s configuration with its own default!

3. Configure the view controller

package com.cheng.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

// Extend the springMVC configuration
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    // Add a view controller
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

        // Enter the cheng request to redirect to the test.html page
        registry.addViewController("/cheng").setViewName("test"); }}Copy the code

Start test, jump successfully!

4, @ EnableWebMvc

If you want to extend springMVC’s configuration, you can add your own webMvcConfiguer@configurationClass without adding @enableWebMVC.

Now, why can’t we add it@EnableWebMvc?

So let’s first take a look@EnableWebMvcThe composition of the:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
Copy the code

@EnableWebMvcOnly one was importedDelegatingWebMvcConfigurationClass, click to analyzeDelegatingWebMvcConfiguration:

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
Copy the code

DelegatingWebMvcConfigurationAnd inheritedWebMvcConfigurationSupportThis class;

Let’s see againWebMvcAutoConfiguration(automatic assembly MVC) source code:

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
Copy the code

This annotation exists in the source code:@ConditionalOnMissingBean(WebMvcConfigurationSupport.class): when there isWebMvcConfigurationSupportMVC autoconfiguration is invalid when you use this class, so you can’t add@EnableWebMvc!