Spring Boot 2.3.0正式發佈:優雅停機、配置文件位置通配符新特性一覽

當大潮退去,才知道誰在裸泳。。關注公眾號【BAT的烏托邦】開啟專欄式學習,拒絕淺嘗輒止。本文 //www.yourbatman.cn 已收錄,裏面一併有Spring技術棧、MyBatis、中間件等小而美的專欄供以學習哦。

前言

各位小夥伴大家好,我是A哥。北京時間2020-05-15,Spring Boot 2.3.0版本正式發佈了,次版本號的升級,一般會有些新特性出來。作為Java Coder的我們有必要一覽它的新new Feature,keep下技術節奏嘛。

A哥「第二時間」知道了這個消息,然後在自己本機(請注意:非生產環境)體驗了一把,然後再結合Spring Boot官方的Release Notes,在這裡給你絮叨絮叨。


關於版本號

Spring Boot代碼庫的版本好採用「國際通用」(我自己yy的)的命名方式:主版本號.次版本號.修訂號,所以通過版本號就能感受到它的變化到底大不大,你升級時是否需要倍加註意等等。那麼此處我就對這種命名方式版本號的各段進行科普一波:

  • 主版本號:完全不兼容。產品定位變化、核心API大規模不兼容(比如包名變了)、架構方式升級不能向下兼容……
    • 舉例:Configuration1.x -> 2.x;Zuul1.x -> 2.x;Spring Boot1.x -> 2.x;Netty4.x -> 5.x
  • 次版本號:相對兼容。一般是增加新特新,刪除掉廢棄的API,修改某些API不兼容。總的來說是影響比較小,在可控範圍內的,但升級時不可掉以輕心,必須做前期調研
  • 修訂號:100%兼容。一般是修復bug、新增無傷大雅的一些特性等,一般想升就升

這次Spring Boot升級到2.3.0版本,屬於次版本號的升級,因此會帶有些新特性,還是值得一看的。

正文

Spring Boot v2.2依然是活躍的維護的版本,Spring Boot遵循的是Pivotal OSS支持策略,從發佈日期起支持主要版本3年。但是呢,一般來說在主要/次要版本發佈時,將會對上個主要版本至少提供12個月的支持(即使超過了3年),以解決關鍵的bug或者安全問題。

關於其它版本的維護活躍狀態和已經EOL的日期,做出如下說明:

  • 2.2.x支持的版本。2019.10發佈,是現在的活躍的主幹
  • 2.1.x支持的版本。2018.10發佈,會支持到2020.10月底
  • 2.0.x:生命已終止的版本。2018.3發佈,2019.4.3停止維護
  • 1.5.x:生命已終止的版本。2017.1發佈,是最後一個1.x分支,2019.8.1停止維護

從官網頁面也可以看出,只有支持的版本才會被列出來,對使用者是有一定的引導作用的:


簡單回憶2.2版本的新特性

很明顯,Spring Boot2.2版本不是本文關心的重點,但為了起到銜接作用,本處把它的核心新特性列一下:

  1. Spring Framework 5.2:重大升級,可以看到它為Cloud Native的努力
  2. JUnit 5:從此版本開始,spring-boot-starter-test默認使用JUnit 5作為單元測試框架
  3. 支持Java13
  4. 性能提升:表現在對所有的自動配置類改為了@Configuration的Lite模式,提升性能。
  5. 新增@ConfigurationPropertiesScan註解,自動掃描@ConfigurationProperties配置類
  6. 支持RSocket

下面我們來了解下本次升級(2.3.0版本)的新特性,分為主要新特性和其它新特性分開闡述。


主要新特性

優雅停機

這個新特性深入人心,是開發者、運維的福音啊。據我了解,很多中小型公司/團隊都是使用kill -9(當然有些比較「溫柔」的團隊也用kill -2)來停服的,這樣暴力「停機」很容易造成業務邏輯執行失敗,導致在一些業務場景下出現數據不一致現象。雖然我們可以通過一些手段(自研)來避免這個問題,但並不是每個公司/團隊都去做了。這不Spring Boot2.3.0版本就內置了這個功能:優雅停機

小知識:kill -2類似於你的Ctrl + C,會觸發shutDownHook事件(從而關閉Spring容器);kill -9就沒啥好說的,殺殺殺

SB所有四個嵌入式web服務器(Jetty、Reactor Netty、Tomcat和Undertow)以及響應性和基於servlet的web應用都支持優雅的關閉。在關閉時,web服務器將不再允許新的請求,並將等待完成的請求給個寬限期讓它完成。當然這個寬限期是可以設置的:可以使用spring.lifecycle.timeout-per-shutdown-phase=xxx來配置,默認值是30s。

注意,注意,注意:默認情況下,優雅關機並沒有開啟(還是立即關機),你僅需添加server.shutdown=graceful配置即可開啟優雅關機(取值參見2.3.0新增的Shutdown枚舉類,默認值參見AbstractConfigurableWebServerFactory.shutdown屬性值)。


配置屬性的調整

這個版本中,一些配置屬性已被重命名或棄用(這會導致不向下兼容,需要特別引起注意),需要你做出調整。

那麼如何知道我現在用的哪些屬性存在不兼容情況呢???官方給了一個很好的解決方案,這裡我用個使用示例教你可以這麼處理:

現狀:在Spring Boot2.2.x環境中你有很多配置,痛點是不知道哪些配置需要配替換成2.3.x中新的。此時你可以在工程下加入這個jar:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
    <scope>runtime</scope>
</dependency>

然後升級你的Spring Boot版本號為2.3.0,重新啟動工程。本處以你配置文件里的spring.http.encoding.enabled=true為例,由於使用了SB的最新版本,因此可以在控制台看到如下日誌輸出:

Property source 'applicationConfig: [classpath:/application.properties]':
	Key: spring.http.encoding.enabled
		Line: 3
		Replacement: server.servlet.encoding.enabled


日誌說夠明確了吧。有了這個好幫手,媽媽就不用再擔心辣么多的配置項需要自己一個個去核對嘍,按照指示一個個的修改即可。

官方說明:完成遷移後,請確保從項目的依賴項中刪除properties-migrator這個模塊。

順道說一下:升級到2.3.0版本號,屬性變化主要是這個:spring.http. -> server.servlet.encoding.、spring.mvc.、spring.codec.


刪除不推薦使用的類/方法/屬性

在該版本中,Spring Boot刪除了2.2版本中不推薦使用的大多數類,方法和屬性。請確保升級之前沒有再調用不推薦使用的方法。針對於此,下面我舉例那些在2.2版本中還「活着」但被棄用(標記有@Deprecated註解),但在2.3版本中已完全刪除的類、方法、屬性:

  1. 方法BindResult#orElseCreate
  2. 屬性LoggingApplicationListener#LOGFILE_BEAN_NAME
  3. 類JodaDateTimeJacksonConfiguration
  4. 類JestAutoConfiguration

即使如此,有些雖然在2.2就已被棄用,但在2.3.0還存在的,如:ConfigurationBeanFactoryMetadata、CompositeHealthIndicator


配置文件位置支持通配符

Spring Boot現在在加載配置文件時支持通配符位置。默認情況下,jar外部的config/*/位置是被支持的。當配置屬性有多個源時,比如在Kubernetes這樣的環境中非常有用。

特點說明:jar包外,jar包外,jar包外,放在內部(比如resource目錄下是沒有此特針的),下面有示例證明

簡單的說,如果你有MySql的配置和Redis配置的話,你就可以把他們分開來放置,隔離性更好目錄也更加清晰了:

  • mysql:/config/mysql/application.properties
  • redis:/config/redis/application.properties

工程目錄如下截圖:

運行程序:

public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(Boot23Demo1Application.class, args);

    ConfigurableEnvironment environment = context.getEnvironment();
    System.out.println(environment.getProperty("mysql.name"));
    System.out.println(environment.getProperty("redis.name"));

    context.close();
}

結果輸出:

mysql
redis

但如果你把文件放在jar包內,形如這樣,是沒有效果的

輸出為null null,因此使用時需要稍加註意哈~


web下的日期轉換支持配置

現在時間/日期的轉換現在可以通過屬性進行配置了,這補充了對格式化日期值的現有支持。比如對於MVC和WebFlux來說,它們的配置項分別如下:

  • spring.mvc.format.date
  • spring.mvc.format.date-time
  • spring.mvc.format.time
  • spring.webflux.format.date
  • spring.webflux.format.date-time
  • spring.webflux.format.time

這個怎麼用,相信大家都會,一看就知道什麼含義。但是,但是,但是:請一定做好充分測試,並且充分考慮兼容性,因為你這動的是接口層的東西~



其它新特性

更改某些依賴最低版本要求

主要體現在如下兩處:

  1. 如果你使用Gradle構建,支持Gradle 6.3+ 。當然嘍5.6.x也支持,只是標記為@Deprecated不推薦使用了
  2. 如果你使用Jetty嵌入式容器,版本要求是Jetty 9.4.22+

核心依賴升級

Spring Boot 2.3遷移到幾個Spring項目的新版本:

  • Spring Data Neumann:你可以理解為它就是之前的Spirng Data工程的升級版
  • Spring HATEOAS 1.1
  • Spring Integration 5.3
  • Spring Kafka 2.5
  • Spring Security 5.3
  • Spring Session Dragonfruit

Spring Boot 2.3的構建與Spring Boot 2.2基於 相同的 Spring Framework和Reactor。

說明:spirng-core么有升級,還是5.2.6版本(SB的2.2.7版本依賴的spring-core也是這個版本)


三方庫依賴升級

  • AssertJ 3.16
  • Cassandra Driver 4.6
  • Elasticsearch 7.6
  • Hibernate Validator 6.1
  • JUnit Jupiter 5.6
  • Kafka 2.5
  • Lettuce 5.3
  • Micrometer 1.5
  • MongoDB 4.0

Spring Data Neumann升級帶來的變化

  • Cassandra:升級到v4版本,帶來了一些變化,如ClusterBuilderCustomizer就木有了~
  • Couchbase:升級到v3版本
  • Elasticsearch:已廢棄的原生Elasticsearch transport直接被刪除了,並且還移除了對Jest的支持。從此版本開始,默認支持Elasticsearch7.5+
  • MongoDB:升級到v4版本

關於Validation

從此版本開始,spring-boot-starter-web不會再把validation帶進來,所以若使用到,你需要自己添加這個spring-boot-starter-validation依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

關於spring-boot-starter-web啟動器新、老版本的區別截圖:


移除一些maven插件

移除了對exec-maven-pluginmaven-site-plugin這兩個插件的管理,所以如果你的工程依賴於這兩個插件,那麼你得顯示的導入(指定版本號)。


支持Java14

Spring Boot 2.3增加了對Java 14的支持。當然Java 8和Java 11也還是被支持的。


Docker支持

在Maven和Gradle插件中添加了對構建包含分層內容的jar文件的支持。分層根據jar內容的更改頻率來分隔它們。這種分離允許更有效地構建Docker映像。未更改的現有層可以與已更改的層一起放在頂部進行重用。

根據您的應用程序,您可能需要調整層的創建方式並添加新層。這可以通過描述如何將jar分成層以及這些層的順序的配置來完成。


Fat Jar支持優化

用Maven和Gradle構建的Fat jar現在包括一個索引文件。當jar被分解時,這個索引文件用於確保類路徑的順序與直接執行jar時相同。


嵌入式Servlet Web Server線程配置

用於配置嵌入式Servlet web服務器使用的線程的配置屬性(包括Jetty, Tomcat, 和Undertow)別移動到了專註於threads的組:erver.jetty.threadsserver.tomcat.threadsserver.undertow.threads。當然嘍,舊的配置屬性目前依然保留着,但被標記為@Deprecated不再推薦使用了~


WebFlux基礎路徑配置

現在可以配置WebFlux應用程序的所有web處理程序的基本路徑。使用pring.webflux.base-path = xxx配置。


活性探測器

Spring Boot現在內置了關於應用程序可用性的探測的能力,可以跟蹤應用程序是否處於活動狀態以及是否準備好處理流量。如果你配置了management.health.probes.enabled=true,那麼健康檢查端點就可以查看你應用的活性和就緒列表,這在在Kubernetes上運行時,這是自動完成的。


Actuator增強

主要是對端點做了些輸出、顯示上的優化。如:

  • /actuator/metrics/:按字母順序排列,這樣你找起來就更方便了
  • DataSource的HealthIndicator健康指示器,現在進行無查詢判斷,而Connection僅做連接可用性驗證而已


好基友Spring Cloud什麼時候跟上?

作為Spring Boot的好基友,按照以往的慣例,他倆的步調不一般都保持基本一致。戒指到當前,Spring Cloud的最新版本是Hoxton SR4,那它是否支持最新的Spring Boot2.3.0呢???答案是:不支持,不支持,不支持。對於Spring Boot這種跨版本升級,一般是有阻斷性變化,所以它的機油SC適配上還需要時間。

這不,官方就公布了Spring Cloud支持Spring Boot 2.3.x的里程碑時間點,也就是它的Hoxton.SR5版本發佈時間點:

Spring Cloud里程碑地址://github.com/spring-cloud/spring-cloud-release/milestones


升級建議:等等

至少要等到2020-5-26號發佈後嘛,至少要等到Spring Boot2.3.x跑一段時間之後嘛,坐在第二排看戲,才是最舒服最穩妥的。


總結

這是A哥奉給大家的,對Spring Boot2.3.0版本新特性的介紹,希望對你有些幫助。有些人可能會這麼說:反正我現在也不用這個版本,沒有必要去了解它。其實非也,如果你2.3.0不去了解,2.4.0不去了解,倘若某一天你突然要從2.0.0版本過度過來使用2.5.x版本了,你會「渾身不舒服」的。你品下,是不是這麼個道理呢?