領先一步
VMware 提供培訓和認證,助您飛速進步。
瞭解更多現在我們回到了起點:Spring Boot 3.4!這個版本將一切整合在一起。當您檢視 Spring Boot 時,請記住它使所有它整合的專案之間的整合標準化,並儘可能平滑地處理使用這些專案時可能出現的任何整合問題。此外,它還提供了使所有這些其他框架使用者受益的功能。
舉例來說:當我們在 Spring Framework 6 和 Spring Boot 3 中引入 GraalVM native image 支援時,它是分三批交付的。第一批:在 Spring Framework 中交付了元件模型、生命週期和核心 SPI。第二批:這個核心元件模型允許所有構建在 Spring Framework 之上的其他專案(例如:Spring Data、Spring Security、Spring Batch、Spring Integration 等)為其專案提供適當的 GraalVM native image 體驗。最後,第三批:Spring Boot 將這種體驗打包成一個內聚的整體,為自身以及一些第三方專案提供 GraalVM 整合,提供構建工具外掛,並總體上安排好所有必須在編譯時發生的事情,在您的程式碼執行之前完成。Spring Boot 還集成了諸如 GraalVM 可達性元資料倉庫和 Buildpacks 對容器化 GraalVM native image 的支援等環境事物。如果做得好,結果令人歎為觀止,Spring Boot 席捲全球是有原因的。它讓您可以專注於生產,也讓 Spring 成為 Spring。(團隊合作成就夢想!)
這個版本也不例外。這個版本有太多令人讚歎的東西了!讓我們像往常一樣回顧一下發行說明中新的和新穎的內容,然後直接深入瞭解我最喜歡的一些新功能(忽略 Spring Boot 3.4 版本引入的專案中隱含的所有驚人功能!)。
HttpRequestFactory
實現的自動配置體驗,這些實現被插入到 RestClient
或 RestTemplate
中。如果您有 Apache HTTP Components,您將獲得一個 HttpComponentsClientHttpRequestFactory
。如果沒有,但您有 Jetty,您將獲得一個 JettyClientHttpRequestFactory
。如果沒有,但您有 Reactor Netty,您將獲得一個 ReactorClientHttpRequestFactory
。如果沒有,但您有較新版本的 JDK,您將獲得 JdkClientHttpRequestFactory
。如果沒有,並且您什麼都沒有,您將獲得一個 SimpleClientHttpRequestFactory
,本質上就是 JDK 中的 HttpURLConnection
。天哪!注意:這個版本還顛倒了預設設定。以前,即使在支援 HttpClient
的 JVM 上,您預設也會得到 HttpURLConnection
。ClientHttpRequestFactoryBuilder
,它允許您以程式設計方式一致地構建這些實現。SIGTERM
) 命令時,Spring Boot 會立即開始關閉。它會允許任何正在進行的事務在可配置的時間段內逐漸完成。然後,它會關閉。在此視窗期間,它將拒絕新的 HTTP 請求等等。@AutoConfigureTestDatabase
,而無需告知測試支援您不想替換它。ecs
)、Graylog Extended Log Format (gelf
) 和 Logstash (logstash
)。要啟用結構化檔案日誌,請將 logging.structured.format.file
設定為 ecs
、gelf
或 logstash
。同樣,設定 logging.structured.format.console
以啟用結構化控制檯日誌。org.apache.activemq
:activemq-broker
,嵌入式 ActiveMQ 就回來了!)META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements
。OtlpMeterRegistry
和 Undertow 都表現正常paketobuildpacks/builder-jammy-java-tiny
。此構建器開箱即用支援 ARM 和 x64 平臺。/actuator/scheduledtasks
端點可以獲取更多關於計劃任務的資訊。如此多的新功能!從何說起呢?我不太確定,所以我想我不會看程式碼,而是看 Spring Boot 控制的執行時體驗,特別是兩個功能:在 Apple Silicon 上使用 build-packs 的 GraalVM native image 和優雅關閉。讓我們看看優雅關閉。這沒什麼好理解的。
讓我們來看一個特別不起眼的小類,它做對了許多事情。
package com.example.bootiful_34.boot;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestClient;
@Controller
@ResponseBody
class GracefulController {
private final RestClient http;
GracefulController(RestClient.Builder http) {
this.http = http.build();
}
@GetMapping("/delay")
String delay() {
return this.http.get().uri("https://httpbin.org/delay/5").retrieve().body(String.class);
}
}
首先,這個類使用了更新的自動配置的 RestClient
構建器,這是 Spring Boot 3.4 中的新功能。我正在執行 Java 21+(正好是 Java 23),所以我獲得了新的 JdkClientHttpRequestFactory
,它基於出色的 java.net.http.HttpClient
。這已經是一個勝利了,我們才剛剛開始!
傳送到此控制器端點的每個請求都會向 HTTPBin 端點發出一個 HTTP 請求。HTTPBin 網站設計用於透過我們在 HTTP 請求中規定的秒數人為延長響應持續時間。在這種情況下,是 5 秒。這是很長的時間!請記住,我們使用的是 Servlet 容器,因此每個請求預設需要一個執行緒。所以您呼叫 localhost:8080/delay
(記住您可能需要登入,因為我們之前已經用 Spring Security 鎖定了應用程式...),它將阻塞五秒鐘。它就這樣坐著,浪費一個執行緒的時間,而預設情況下執行緒資源非常寶貴。幸運的是,這是 Spring Boot,所以只需翻轉一個配置開關,我們就啟用了 Java 21 的虛擬執行緒:spring.threads.virtual.enabled=true
。
現在,當用戶發出請求時,RestClient 發起一個請求,當它在那裡等待五秒鐘時,JVM 會自動將作業系統執行緒上的請求移動到一種等待狀態。為什麼這很重要?因為現在其他人可以免費使用該執行緒了(與此同時)!這會帶來更好的、無負罪感的可伸縮性。但這並不是一個新功能。您可以在 Spring Boot 3.2 中使用它。
這種情況的好處是每個請求也需要時間完成。當然是五秒加上網路延遲。那麼,如果操作員、Kubernetes 或 Cloud Foundry 過來並想要關閉應用程式會發生什麼?我們還在等待請求完成!JVM 也是如此。預設是 30 秒,您可以透過 spring.lifecycle.timeout-per-shutdown-phase=30s
進行配置。因此,如果平臺關閉應用程式(您可以透過在 JetBrains IntelliJ IDEA 中按下紅色方塊來模擬),它會等待最多 30 秒來完成任何正在進行的請求。然後它會關閉。否則,它會立即關閉。很好。
對於 Apple Silicon 使用者來說,一個不錯的改進是 Buildpacks 支援已更新,可以在 Apple Silicon 上正常工作。
那麼,讓我們將這個應用程式本身變成一個 GraalVM native image。在 bootiful-34
資料夾的根目錄下執行以下命令。
./mvnw -DskipTests clean -Pnative spring-boot:build-image
這是我在 Apple Silicon 支援的 Apple M4 筆記型電腦上用於編譯然後執行的指令碼。
#!/usr/bin/env bash
rm -rf target
./mvnw -DskipTests spring-javaformat:apply
./mvnw -DskipTests -Pnative spring-boot:build-image
這是我用來執行的指令碼。這假設您在本地執行 Docker 或類似 Docker 的東西,並且在您的主機作業系統中有一個環境變數(像我一樣)指定了名為 SPRING_AI_OPENAI_API_KEY
的 OpenAI API 金鑰。
#!/usr/bin/env bash
export SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal/mydatabase
docker run \
-e SPRING_DATASOURCE_URL=$SPRING_DATASOURCE_URL \
-e SPRING_AI_OPENAI_API_KEY=$SPRING_AI_OPENAI_API_KEY \
docker.io/library/bootiful-34:0.0.1-SNAPSHOT
你知道什麼讓我大吃一驚嗎?有時,至少在我的機器上,執行在 Apple Silicon 上的帶有 GraalVM native image 二進位制檔案的 Linux 容器比直接編譯成 macOS native binary 並在 macOS 上執行要快!我完全不知道是怎麼回事!這個應用程式簡直是個大雜燴!我們有 web 伺服器、一個 Spring Batch Job
、幾個 Spring Integration 流、大量的 SQL DataSource
訪問、Spring Modulith、本地呼叫函式的 Spring AI、三種不同的安全型別以及一個功能齊全的 OAuth IDP(Spring Authorization Server)、一些 HTTP 端點、一些 Spring Data JDBC 實體和倉庫,以及更多。所以,請相信我,這不是典型的工作負載,我沒有預料到這個二進位制檔案在我的機器上的 Linux 環境下執行會更快。在 macOS 上直接執行,啟動時間有時在 0.450 到 0.5 秒之間。在 Docker 中,我看到它執行得像 0.264 秒一樣快。我感到困惑!
在我更典型的以應用程式為中心的服務中,數字甚至更加明顯。我在同一個 Github 倉庫中有一個更簡單的應用程式,名為 demo
。demo
只是 Spring Data JDBC 連線 PostgreSQL 和 Spring MVC。它什麼都不做。Buildpacks 版本的 native image 啟動時間穩定在 0.050 秒左右,而 macOS native image 啟動時間在 0.080 秒左右!這不是完全翻倍,但也不是什麼都沒有!我喜歡 Buildpacks!現在在我的本地機器上測試一切正常真是太好了。
Spring Boot 提供了一個堅實的基礎,我們的一些其他專案可以在此基礎上構建。已有兩個專案隨 Spring Boot 3.4 支援一起釋出:Spring Modulith 和 Spring AI。所以,我在這裡將介紹這兩個。另一個基於 Spring Boot 3.4 的專案——Spring Cloud——將很快推出。
Spring Boot 3.4 非常棒。請記住,這是我們明年釋出 Spring Boot 4.0 之前的最後幾個版本之一,所以在升級時,請注意任何棄用。最好現在就整理和篩查它們!