1. 程式人生 > >Spring Boot2 系列教程(十八)Spring Boot 中自定義 SpringMVC 配置

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 ,這個又是幹什麼用的呢?

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

  • 純 Java 程式碼搭建 SSM 環境

這篇文章我放棄了 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 乾貨!

相關推薦

Spring Boot2 系列教程()Spring Boot 定義 SpringMVC 配置

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

Spring Boot2 系列教程(一)Spring Boot 的靜態資源配置

當我們使用 SpringMVC 框架時,靜態資源會被攔截,需要新增額外配置,之前老有小夥伴在微信上問鬆哥 Spring Boot 中的靜態資源載入問題:“鬆哥,我的 HTML 頁面好像沒有樣式?”,今天我就通過一篇文章,來和大夥仔細聊一聊這個問題。 1. SSM 中的配置 要講 Spring Boot 中的問

Spring Boot2 系列教程(九)Spring Boot 整合 JdbcTemplate

在 Java 領域,資料持久化有幾個常見的方案,有 Spring 自帶的 JdbcTemplate 、有 MyBatis,還有 JPA,在這些方案中,最簡單的就是 Spring 自帶的 JdbcTemplate 了,這個東西雖然沒有 MyBatis 那麼方便,但是比起最開始的 Jdbc 已經強了很多了,它沒有

Spring Boot2 系列教程()Spring Boot 整合 Freemarker

今天來聊聊 Spring Boot 整合 Freemarker。 Freemarker 簡介 這是一個相當老牌的開源的免費的模版引擎。通過 Freemarker 模版,我們可以將資料渲染成 HTML 網頁、電子郵件、配置檔案以及原始碼等。Freemarker 不是面向終端使用者的,而是一個 Java 類庫,我

Spring Boot2 系列教程(二)建立 Spring Boot 專案的三種方式

我最早是 2016 年底開始寫 Spring Boot 相關的部落格,當時使用的版本還是 1.4.x ,文章發表在 CSDN 上,閱讀量最大的一篇有 43W+,如下圖: 2017 年由於種種原因,就沒有再繼續更新 Spring Boot 相關的部落格了,2018年又去寫書了,也沒更新,現在 Spring

Spring Boot2 系列教程(三)理解 Spring Boot 專案的 parent

前面和大夥聊了 Spring Boot 專案的三種建立方式,這三種建立方式,無論是哪一種,建立成功後,pom.xml 座標檔案中都有如下一段引用: <parent> <groupId>org.springframework.boot</groupId> &l

Spring Boot2 系列教程(四)理解Spring Boot 配置檔案 application.properties

在 Spring Boot 中,配置檔案有兩種不同的格式,一個是 properties ,另一個是 yaml 。 雖然 properties 檔案比較常見,但是相對於 properties 而言,yaml 更加簡潔明瞭,而且使用的場景也更多,很多開源專案都是使用 yaml 進行配置(例如 Hexo)。除了簡潔

Spring Boot2 系列教程(二)@ControllerAdvice 的三種使用場景

嚴格來說,本文並不算是 Spring Boot 中的知識點,但是很多學過 SpringMVC 的小夥伴,對於 @ControllerAdvice 卻並不熟悉,Spring Boot 和 SpringMVC 一脈相承,@ControllerAdvice 在 Spring Boot 中也有廣泛的使用場景,因此本文

Spring Boot2 系列教程(四)CORS 解決跨域問題

今天和小夥伴們來聊一聊通過CORS解決跨域問題。 同源策略 很多人對跨域有一種誤解,以為這是前端的事,和後端沒關係,其實不是這樣的,說到跨域,就不得不說說瀏覽器的同源策略。 同源策略是由 Netscape 提出的一個著名的安全策略,它是瀏覽器最核心也最基本的安全功能,現在所有支援 JavaScript 的瀏覽

Spring Boot2 系列教程(五)定義系統啟動任務的兩種方式

在 Servlet/Jsp 專案中,如果涉及到系統任務,例如在專案啟動階段要做一些資料初始化操作,這些操作有一個共同的特點,只在專案啟動時進行,以後都不再執行,這裡,容易想到web基礎中的三大元件( Servlet、Filter、Listener )之一 Listener ,這種情況下,一般定義一個 Serv

Spring Boot2 系列教程(六)定時任務的兩種實現方式

在 Spring + SpringMVC 環境中,一般來說,要實現定時任務,我們有兩中方案,一種是使用 Spring 自帶的定時任務處理器 @Scheduled 註解,另一種就是使用第三方框架 Quartz ,Spring Boot 源自 Spring+SpringMVC ,因此天然具備這兩個 Spring

Spring Boot2 系列教程(七)SpringBoot 整合 Swagger2

前後端分離後,維護介面文件基本上是必不可少的工作。 一個理想的狀態是設計好後,介面文件發給前端和後端,大夥按照既定的規則各自開發,開發好了對接上了就可以上線了。當然這是一種非常理想的狀態,實際開發中卻很少遇到這樣的情況,介面總是在不斷的變化之中,有變化就要去維護,做過的小夥伴都知道這件事有多麼頭大!還好,有一

Spring Boot2 系列教程(二)Spring Boot 整合 Session 共享

這篇文章是鬆哥的原創,但是在第一次釋出的時候,忘了標記原創,結果被好多號轉發,導致我後來整理的時候自己沒法標記原創了。寫了幾百篇原創技術乾貨了,有一兩篇忘記標記原創進而造成的一點點小小損失也能接受,不過還是要和小夥伴們說明一下。 在傳統的單服務架構中,一般來說,只有一個伺服器,那麼不存在 Session

Spring Boot2 系列教程()Spring Boot 配置 Https

https 現在已經越來越普及了,特別是做一些小程式或者公眾號開發的時候,https 基本上都是剛需了。 不過一個 https 證書還是挺費錢的,個人開發者可以在各個雲服務提供商那裡申請一個免費的證書。我印象中有效期一年,可以申請 20 個。 今天要和大家聊的是在 Spring Boot 專案中,如何開啟 h

Spring Boot2 系列教程(二四)Spring Boot 整合 Jpa

Spring Boot 中的資料持久化方案前面給大夥介紹了兩種了,一個是 JdbcTemplate,還有一個 MyBatis,JdbcTemplate 配置簡單,使用也簡單,但是功能也非常有限,MyBatis 則比較靈活,功能也很強大,據我所知,公司採用 MyBatis 做資料持久化的相當多,但是 MyBat

Spring Boot2 系列教程(二五)Spring Boot 整合 Jpa 多資料來源

本文是 Spring Boot 整合資料持久化方案的最後一篇,主要和大夥來聊聊 Spring Boot 整合 Jpa 多資料來源問題。在 Spring Boot 整合JbdcTemplate 多資料來源、Spring Boot 整合 MyBatis 多資料來源以及 Spring Boot 整合 Jpa 多資料

Spring Boot2 系列教程(二六)Spring Boot 整合 Redis

在 Redis 出現之前,我們的快取框架各種各樣,有了 Redis ,快取方案基本上都統一了,關於 Redis,鬆哥之前有一個系列教程,尚不瞭解 Redis 的小夥伴可以參考這個教程: Redis 教程合集 使用 Java 操作 Redis 的方案很多,Jedis 是目前較為流行的一種方案,除了 Jedi

Spring Boot2 系列教程(二九)Spring Boot 整合 Redis

經過 Spring Boot 的整合封裝與自動化配置,在 Spring Boot 中整合Redis 已經變得非常容易了,開發者只需要引入 Spring Data Redis 依賴,然後簡單配下 redis 的基本資訊,系統就會提供一個 RedisTemplate 供開發者使用,但是今天鬆哥想和大夥聊的不是這種

Spring Boot2 系列教程(三)Spring Boot 整合 Ehcache

用慣了 Redis ,很多人已經忘記了還有另一個快取方案 Ehcache ,是的,在 Redis 一統江湖的時代,Ehcache 漸漸有點沒落了,不過,我們還是有必要了解下 Ehcache ,在有的場景下,我們還是會用到 Ehcache。 今天鬆哥就來和大家聊聊 Spring Boot 中使用 Ehcach

Spring Boot2 系列教程(三一)Spring Boot 構建 RESTful 風格應用

RESTful ,到現在相信已經沒人不知道這個東西了吧!關於 RESTful 的概念,我這裡就不做過多介紹了,傳統的 Struts 對 RESTful 支援不夠友好 ,但是 SpringMVC 對於 RESTful 提供了很好的支援,常見的相關注解有: @RestController @GetMapping