Spring Boot2 系列教程(十八)Spring Boot 中自定義 SpringMVC 配置

用過 Spring Boot 的小夥伴都知道,我們只需要在項目中引入 spring-boot-starter-web 依賴,SpringMVC 的一整套東西就會自動給我們配置好,但是,真實的項目環境比較複雜,系統自帶的配置不一定滿足我們的需求,往往我們還需要結合實際情況自定義配置。

自定義配置就有講究了,由於 Spring Boot 的版本變遷,加上這一塊本身就有幾個不同寫法,很多小夥伴在這裏容易搞混,今天鬆哥就來和大家說一說這個問題。

概覽

首先我們需要明確,跟自定義 SpringMVC 相關的類和註解主要有如下四個:

  • WebMvcConfigurerAdapter
  • WebMvcConfigurer
  • WebMvcConfigurationSupport
  • @EnableWebMvc

這四個中,除了第四個是註解,另外三個兩個類一個接口,裏邊的方法看起來好像都類似,但是實際使用效果卻大不相同,因此很多小夥伴容易搞混,今天鬆哥就來和大家聊一聊這個問題。

WebMvcConfigurerAdapter

我們先來看 WebMvcConfigurerAdapter,這個是在 Spring Boot 1.x 中我們自定義 SpringMVC 時繼承的一個抽象類,這個抽象類本身是實現了 WebMvcConfigurer 接口,然後抽象類裏邊都是空方法,我們來看一下這個類的聲明:

public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
    //各種 SpringMVC 配置的方法
}

再來看看這個類的註釋:

/**
 * An implementation of {@link WebMvcConfigurer} with empty methods allowing
 * subclasses to override only the methods they're interested in.
 * @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made
 * possible by a Java 8 baseline) and can be implemented directly without the
 * need for this adapter
 */

這段註釋關於這個類說的很明白了。同時我們也看到,從 Spring5 開始,由於我們要使用 Java8,而 Java8 中的接口允許存在 default 方法,因此官方建議我們直接實現 WebMvcConfigurer 接口,而不是繼承 WebMvcConfigurerAdapter 。

也就是說,在 Spring Boot 1.x 的時代,如果我們需要自定義 SpringMVC 配置,直接繼承 WebMvcConfigurerAdapter 類即可。

WebMvcConfigurer

根據上一小節的解釋,小夥伴們已經明白了,WebMvcConfigurer 是我們在 Spring Boot 2.x 中實現自定義配置的方案。

WebMvcConfigurer 是一個接口,接口中的方法和 WebMvcConfigurerAdapter 中定義的空方法其實一樣,所以用法上來說,基本上沒有差別,從 Spring Boot 1.x 切換到 Spring Boot 2.x ,只需要把繼承類改成實現接口即可。

鬆哥在之前的案例中(40 篇原創乾貨,帶你進入 Spring Boot 殿堂!),凡是涉及到自定義 SpringMVC 配置的地方,也都是通過實現 WebMvcConfigurer 接口來完成的。

WebMvcConfigurationSupport

前面兩個都好理解,還有一個 WebMvcConfigurationSupport ,這個又是幹什麼用的呢?

鬆哥之前有一篇文章中用過這個類,不知道小夥伴們有沒有留意,就是下面這篇:

這篇文章我放棄了 Spring 和 SpringMVC 的 xml 配置文件,轉而用 Java 代替這兩個 xml 配置。那麼在這裏我自定義 SpringMVC 配置的時候,就是通過繼承 WebMvcConfigurationSupport 類來實現的。在 WebMvcConfigurationSupport 類中,提供了用 Java 配置 SpringMVC 所需要的所有方法。我們來看一下這個方法的摘要:

有一點眼熟,可能有小夥伴發現了,這裏的方法其實和前面兩個類中的方法基本是一樣的。

在這裏首先大家需要明確的是,WebMvcConfigurationSupport 類本身是沒有問題的,我們自定義 SpringMVC 的配置是可以通過繼承 WebMvcConfigurationSupport 來實現的。但是繼承 WebMvcConfigurationSupport 這種操作我們一般只在 Java 配置的 SSM 項目中使用,Spring Boot 中基本上不會這麼寫,爲什麼呢?

小夥伴們知道,Spring Boot 中,SpringMVC 相關的自動化配置是在 WebMvcAutoConfiguration 配置類中實現的,那麼我們來看看這個配置類的生效條件:

@Configuration
@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 {
}

我們從這個類的註解中可以看到,它的生效條件有一條,就是當不存在 WebMvcConfigurationSupport 的實例時,這個自動化配置纔會生生效。因此,如果我們在 Spring Boot 中自定義 SpringMVC 配置時選擇了繼承 WebMvcConfigurationSupport,就會導致 Spring Boot 中 SpringMVC 的自動化配置失效。

Spring Boot 給我們提供了很多自動化配置,很多時候當我們修改這些配置的時候,並不是要全盤否定 Spring Boot 提供的自動化配置,我們可能只是針對某一個配置做出修改,其他的配置還是按照 Spring Boot 默認的自動化配置來,而繼承 WebMvcConfigurationSupport 來實現對 SpringMVC 的配置會導致所有的 SpringMVC 自動化配置失效,因此,一般情況下我們不選擇這種方案。

在 Java 搭建的 SSM 項目中(純 Java 代碼搭建 SSM 環境),因爲本身就沒什麼自動化配置,所以我們使用了繼承 WebMvcConfigurationSupport。

@EnableWebMvc

最後還有一個 @EnableWebMvc 註解,這個註解很好理解,它的作用就是啓用 WebMvcConfigurationSupport。我們來看看這個註解的定義:

/**
 * Adding this annotation to an {@code @Configuration} class imports the Spring MVC
 * configuration from {@link WebMvcConfigurationSupport}, e.g.:

可以看到,加了這個註解,就會自動導入 WebMvcConfigurationSupport,所以在 Spring Boot 中,我們也不建議使用 @EnableWebMvc 註解,因爲它一樣會導致 Spring Boot 中的 SpringMVC 自動化配置失效。

總結

不知道上面的解釋小夥伴有沒有看懂?我再簡單總結一下:

  1. Spring Boot 1.x 中,自定義 SpringMVC 配置可以通過繼承 WebMvcConfigurerAdapter 來實現。
  2. Spring Boot 2.x 中,自定義 SpringMVC 配置可以通過實現 WebMvcConfigurer 接口來完成。
  3. 如果在 Spring Boot 中使用繼承 WebMvcConfigurationSupport 來實現自定義 SpringMVC 配置,或者在 Spring Boot 中使用了 @EnableWebMvc 註解,都會導致 Spring Boot 中默認的 SpringMVC 自動化配置失效。
  4. 在純 Java 配置的 SSM 環境中,如果我們要自定義 SpringMVC 配置,有兩種辦法,第一種就是直接繼承自 WebMvcConfigurationSupport 來完成 SpringMVC 配置,還有一種方案就是實現 WebMvcConfigurer 接口來完成自定義 SpringMVC 配置,如果使用第二種方式,則需要給 SpringMVC 的配置類上額外添加 @EnableWebMvc 註解,表示啓用 WebMvcConfigurationSupport,這樣配置纔會生效。換句話說,在純 Java 配置的 SSM 中,如果你需要自定義 SpringMVC 配置,你離不開 WebMvcConfigurationSupport ,所以在這種情況下建議通過繼承 WebMvcConfigurationSupport 來實現自動化配置。

不知道小夥伴們有沒有看懂呢?有問題歡迎留言討論。

關注公衆號【江南一點雨】,專注於 Spring Boot+微服務以及前後端分離等全棧技術,定期視頻教程分享,關注後回覆 Java ,領取鬆哥爲你精心準備的 Java 乾貨!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章