1. Introduction

In this article, I describe a serious warning that can be reported when you upgrade spring 4.xx (or lower) to Spring 5.xx and Spring Boot 1.xx to Spring Boot 2.xx: “Warning:The type WebMvcConfigurerAdapter is deprecated.”

2. Cause of the warning

If we use the Spring 5.xx (or Spring Boot 2.xx) version to build or upgrade the application, this warning will appear when configuring WebMvc. This is because in earlier Spring releases, when configuring Web applications, This can be accomplished by extending the WebMvcConfigurerAdapter class.

package com.ramostear.page;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/** * Example Web application configuration for Spring 4(or Spring Boot 1.x) version *@author ramostear
 * @create-time 2019/4/18 0018-1:38
 */
@Configuration
public class OldMvcConfig extends WebMvcConfigurerAdapter{

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        super.configurePathMatch(configurer);
        configurer.setUseSuffixPatternMatch(false);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/ * *")
                .addResourceLocations("classpath:/static/")
                .addResourceLocations("classpath:/META-INF/resources/")
                .addResourceLocations("classpath:/public/")
                .addResourceLocations("classpath:/resources/");
        super.addResourceHandlers(registry); }}Copy the code

Webmvcconfigeradapter is an abstract class that implements the WebMvcConfigurer interface and provides empty implementations of all the methods that we can override in subclasses to implement our own configurations, such as view resolvers, interceptors, and cross-domain support… In Java 8, you can use the default keyword to add a default method to an interface due to Java version updates. Spring also supports this new feature in Java 8 during the upgrade. Here’s a simple implementation of defining a default method for an interface in Java 8:

public interface MyInterface{
    
    default void sayHello(a){
        / /...
    }
    
    void sayName(a){}
    
    String writeName(a){}
    
    / /...
}
Copy the code

3. Solutions

As mentioned earlier, starting with Spring 5, the WebMvcConfigure interface contains default implementations of all the methods in the WebMvcConfigurerAdapter class, so the WebMvcConfigurerAdapter is a dead end. Here is an example of the WebMvcConfigurerAdapter class:

/**
 * An implementation of {@link WebMvcConfigurer} with empty methods allowing
 * subclasses to override only the methods they're interested in.
 *
 * @author Rossen Stoyanchev
 * @since 3.1
 * @deprecatedAs of 5.0 {@linkWebMvcConfigurer} has default methods (made * possible by a Java 8 baseline) and can be implemented directly without the  * need for this adapter */
@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {

	/ * * * {@inheritDoc}
	 * <p>This implementation is empty.
	 */
	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {}/ * * * {@inheritDoc}
	 * <p>This implementation is empty.
	 */
	@Override
	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}... }Copy the code

Interesting note: We can configure the Web application by implementing the methods in the WebMvcConfigure interface without having the WebMvcConfigurerAdapter, the middleman, earn the difference.

With this in mind, we found a way to eliminate warnings by directly implementing the WebMvcConfigurer interface. Before we get ready to work with WebMvcConfigurer, let’s look at the basics of this interface:

public interface WebMvcConfigurer {

	default void configurePathMatch(PathMatchConfigurer configurer) {}/** * Configure content negotiation options. */
	default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}/** * Configure asynchronous request handling options. */
	default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}... }Copy the code

Now we are ready to configure the Web application, which looks like this:

/** * Example Web application configuration for Spring 5 (or Spring Boot 2.x) version *@author ramostear
 * @create-time 2019/4/18 0018-1:40
 */
@Configuration
public class MvcConfigure implements WebMvcConfigurer{

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(false);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/ * *")
                .addResourceLocations("classpath:/static/")
                .addResourceLocations("classpath:/public/")
                .addResourceLocations("classpath:/resources/"); }}Copy the code

This simply eliminates the warning and changes the inherited WebMvcConfigurerAdapter class to implement the WebMvcConfigurer interface, leaving everything else unchanged. One thing to note, however, is that if you are upgrading an older application, you will need to clear the calling code for super() from the method.

At this point, our program is happy to play again. So is there any other way to get around the warning than eliminating the way the middlemen earn the difference? The answer, of course, is yes. We in addition to eliminating intermediaries from WebMvcConfigurer configuration of the Web application ways, can also directly from WebMvcConfigurationSupport this configuration “supplier” in the hands of access to configuration. WebMvcConfigurationSupport is a provides in the Java programming way to configure the Web application configuration main class, so we can get away from the allocation of suppliers of the Web application configuration mode. The method is simple, just extend this class and override the corresponding method. As above, let’s first look at the internal structure of this class:

public class WebMvcConfigurationSupport implements ApplicationContextAware.ServletContextAware {.../**
	 * Provide access to the shared handler interceptors used to configure
	 * {@link HandlerMapping} instances with.
	 * <p>This method cannot be overridden; use {@link #addInterceptors} instead.
	 */
	protected final Object[] getInterceptors() {
		...
	}
    
    /**
	 * Return a handler mapping ordered at Integer.MAX_VALUE-1 with mapped
	 * resource handlers. To configure resource handling, override
	 * {@link #addResourceHandlers}.
	 */
	@Bean
	@Nullable
	public HandlerMapping resourceHandlerMapping(a) {... handlerMapping.setPathMatcher(mvcPathMatcher()); handlerMapping.setUrlPathHelper(mvcUrlPathHelper()); handlerMapping.setInterceptors(getInterceptors()); handlerMapping.setCorsConfigurations(getCorsConfigurations());returnhandlerMapping; }}Copy the code

Are you seeing anything familiar, interceptors, static resource mappings, etc… To configure our Web application (and annotate the extension class with @Configuration), we simply need to extend this class and override its methods. The example code looks like this:

/** * The second configuration option to eliminate warnings *@author ramostear
 * @create-time 2019/4/7 0007-4:10
 */
@Configuration
public class MvcConfig extends WebMvcConfigurationSupport {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        super.configurePathMatch(configurer);
        configurer.setUseSuffixPatternMatch(false);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/ * *")
                .addResourceLocations("classpath:/static/")
                .addResourceLocations("classpath:/META-INF/resources/")
                .addResourceLocations("classpath:/public/")
                .addResourceLocations("classpath:/resources/");
        super.addResourceHandlers(registry); }}Copy the code

4. The conclusion

In this article, a quick look at two different scenarios to eliminate the serious warning that the WebMvcConfigurerAdapter class is deprecated due to the Spring(or Spring Boot) version upgrade. This technology share to end here, thank you for your patience to read. If you have a better solution for the same problem, let me know in the comments section below.

The original link: www.ramostear.com/articles/af…