1. 程式人生 > >SpringBoot2.0學習筆記:(七) Spring Boot棄用的WebMvcConfigurerAdapter

SpringBoot2.0學習筆記:(七) Spring Boot棄用的WebMvcConfigurerAdapter

我們都知道,在Spring Boot程式引入Web模組之後,會自動進行一系列有關Spring Mvc的配置,其自動配置類為:org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration

在這個類中,Spring Boot給我們配置好了檢視解析器、靜態資源、訊息轉換器、區域資訊解析器、首頁、歡迎頁等等內容。

這裡並不分析WebMvcAutoConfiguration這個類,要說的是WebMvcConfigurerAdapter這個適配類。

Spring Boot並不僅僅給我們自動配置好了關於Spring MVC的配置,而且為了方便的進行擴充套件,還給我們提供了

WebMvcConfigurerAdapter這個適配類,只需要我們自己實現了這個類,就可以自定義比如檢視解析器、區域資訊解析器這些元件。

在Spring Boot2.0版本中,WebMvcConfigurerAdapter這個類被棄用了。

@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {

那麼我們如何來擴充套件關於MVC的配置呢?

1.繼承WebMvcConfigurationSupport

仔細看一下WebMvcConfigurationSupport這個類的話,可以發現其中有很多add…方法:

/**
* Override this method to add Spring MVC interceptors for
* pre- and post-processing of controller invocation.
* @see InterceptorRegistry
 */
protected void addInterceptors(InterceptorRegistry registry) {
}

/**
 * Override this method to add view controllers.
 * @see ViewControllerRegistry
*/
protected
void addViewControllers(ViewControllerRegistry registry) { } ......

繼承WebMvcConfigurationSupport之後,可以使用這些add…方法新增自定義的攔截器、試圖解析器等等這些元件。如下:

@Configuration
public class NativeMvcConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/login.html").setViewName("login");
    }
}

但這裡有個問題就是,當你繼承了WebMvcConfigurationSupport並將之註冊到容器中之後,Spring Boot有關MVC的自動配置就不生效了。

可以看一下Spring Boot啟動WebMVC自動配置的條件:

@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
		ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

其中一個條件就是**@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)**,只有當容器中沒有WebMvcConfigurationSupport這個型別的元件的時候,才會啟動自動配置。

所以當我們繼承WebMvcConfigurationSupport之後,除非你自己對程式碼把控的相當的好,在繼承類中重寫了一系列有關WebMVC的配置,否則可能就會遇到靜態資源訪問不到,返回資料不成功這些一系列問題了。

2. 實現WebMvcConfigurer介面

我們知道,Spring Boot2.0是基於Java8的,Java8有個重大的改變就是介面中可以有default方法,而default方法是不需要強制實現的。上述的WebMvcConfigurerAdapter類就是實現了WebMvcConfigurer這個介面,所以我們不需要繼承WebMvcConfigurerAdapter類,可以直接實現WebMvcConfigurer介面,用法與繼承這個適配類是一樣的。如:

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/login.html").setViewName("login");
    }

    @Bean
    public LocaleResolver localeResolver(){
        return new NativeLocaleResolver();
    }

    protected static class NativeLocaleResolver implements LocaleResolver{

        @Override
        public Locale resolveLocale(HttpServletRequest request) {
            String language = request.getParameter("language");
            Locale locale = Locale.getDefault();
            if(!StringUtils.isEmpty(language)){
                String[] split = language.split("_");
                locale = new Locale(split[0],split[1]);
            }
            return locale;
        }

        @Override
        public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

        }
    }
}

這兩種方法都可以作為WebMVC的擴充套件,去自定義配置。區別就是繼承WebMvcConfigurationSupport會使Spring Boot關於WebMVC的自動配置失效,需要自己去實現全部關於WebMVC的配置,而實現WebMvcConfigurer介面的話,Spring Boot的自動配置不會失效,可以有選擇的實現關於WebMVC的配置。