SpringApplication
SpringApplication 類提供了一種方便的方式來引導從 main() 方法啟動的 Spring 應用程式。在許多情況下,您可以委託給靜態的 SpringApplication.run(Class, String…) 方法,如下例所示
-
Java
-
Kotlin
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
當您的應用程式啟動時,您應該看到類似以下的輸出
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.0.0)
2025-11-20T16:37:28.294Z INFO 128420 --- [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 25.0.1 with PID 128420 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2025-11-20T16:37:28.322Z INFO 128420 --- [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2025-11-20T16:37:31.896Z INFO 128420 --- [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2025-11-20T16:37:31.952Z INFO 128420 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-11-20T16:37:31.953Z INFO 128420 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.14]
2025-11-20T16:37:32.122Z INFO 128420 --- [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 3543 ms
2025-11-20T16:37:33.770Z INFO 128420 --- [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2025-11-20T16:37:33.799Z INFO 128420 --- [ main] o.s.b.d.f.logexample.MyApplication : Started MyApplication in 7.034 seconds (process running for 8.198)
2025-11-20T16:37:33.856Z INFO 128420 --- [ionShutdownHook] o.s.boot.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2025-11-20T16:37:33.915Z INFO 128420 --- [tomcat-shutdown] o.s.boot.tomcat.GracefulShutdown : Graceful shutdown complete
預設情況下,會顯示 INFO 級別的日誌訊息,包括一些相關的啟動詳細資訊,例如啟動應用程式的使用者。如果需要 INFO 以外的日誌級別,可以進行設定,如日誌級別中所述。應用程式版本是使用主應用程式類包中的實現版本確定的。可以透過將 spring.main.log-startup-info 設定為 false 來關閉啟動資訊日誌記錄。這將同時關閉應用程式活動配置檔案的日誌記錄。
要在啟動期間新增額外的日誌記錄,您可以在 SpringApplication 的子類中覆蓋 logStartupInfo(boolean)。 |
啟動失敗
如果您的應用程式啟動失敗,註冊的 FailureAnalyzer bean 將有機會提供專門的錯誤訊息和具體的解決問題的操作。例如,如果您在埠 8080 上啟動一個 Web 應用程式,而該埠已被佔用,您應該看到類似以下訊息的內容
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that is listening on port 8080 or configure this application to listen on another port.
Spring Boot 提供了許多 FailureAnalyzer 實現,您可以新增您自己的。 |
如果沒有失敗分析器能夠處理異常,您仍然可以顯示完整的條件報告,以便更好地瞭解出了什麼問題。為此,您需要啟用 debug 屬性或為 ConditionEvaluationReportLoggingListener 啟用 DEBUG 日誌記錄。
例如,如果您正在使用 java -jar 執行應用程式,您可以按如下方式啟用 debug 屬性
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
延遲初始化
SpringApplication 允許應用程式延遲初始化。當啟用延遲初始化時,bean 會在需要時建立,而不是在應用程式啟動期間建立。因此,啟用延遲初始化可以減少應用程式啟動所需的時間。在 Web 應用程式中,啟用延遲初始化將導致許多與 Web 相關的 bean 直到接收到 HTTP 請求時才會被初始化。
延遲初始化的一個缺點是它可能會延遲應用程式問題的發現。如果一個配置錯誤的 bean 被延遲初始化,那麼在啟動期間將不再發生故障,並且只有在 bean 初始化時問題才會顯現出來。還必須注意確保 JVM 有足夠的記憶體來容納應用程式的所有 bean,而不僅僅是那些在啟動期間初始化的 bean。由於這些原因,預設情況下不啟用延遲初始化,建議在啟用延遲初始化之前對 JVM 的堆大小進行微調。
延遲初始化可以透過 SpringApplicationBuilder 上的 lazyInitialization 方法或 SpringApplication 上的 setLazyInitialization 方法以程式設計方式啟用。或者,也可以使用 spring.main.lazy-initialization 屬性啟用,如下例所示
-
屬性
-
YAML
spring.main.lazy-initialization=true
spring:
main:
lazy-initialization: true
如果您希望停用某些 bean 的延遲初始化,同時對應用程式的其餘部分使用延遲初始化,則可以使用 @Lazy(false) 註解將它們的延遲屬性顯式設定為 false。 |
定製 Banner
可以透過在類路徑中新增 banner.txt 檔案或將 spring.banner.location 屬性設定為此類檔案的位置來更改啟動時列印的 banner。如果檔案的編碼不是 UTF-8,您可以設定 spring.banner.charset。
在您的 banner.txt 檔案中,您可以使用 Environment 中可用的任何鍵以及以下任何佔位符
| 變數 | 描述 |
|---|---|
|
您的應用程式的版本號,如 |
|
您的應用程式的版本號,如 |
|
您正在使用的 Spring Boot 版本。例如 |
|
您正在使用的 Spring Boot 版本,格式化為顯示(用括號括起來並加上 |
|
其中 |
|
您的應用程式的標題,如 |
如果要以程式設計方式生成 banner,可以使用 SpringApplication.setBanner(…) 方法。使用 Banner 介面並實現您自己的 printBanner() 方法。 |
您還可以使用 spring.main.banner-mode 屬性來確定 banner 是列印到 System.out (console)、傳送到配置的日誌記錄器 (log) 還是根本不生成 (off)。
列印的 banner 作為單例 bean 註冊,名稱為:springBootBanner。
|
要使用 |
定製 SpringApplication
如果 SpringApplication 的預設設定不符合您的喜好,您可以建立一個本地例項並進行定製。例如,要關閉 banner,您可以這樣編寫
-
Java
-
Kotlin
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
import org.springframework.boot.Banner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args) {
setBannerMode(Banner.Mode.OFF)
}
}
傳遞給 SpringApplication 的建構函式引數是 Spring bean 的配置源。在大多數情況下,它們是對 @Configuration 類的引用,但它們也可以是 @Component 類的直接引用。 |
也可以透過使用 application.properties 檔案來配置 SpringApplication。有關詳細資訊,請參閱外部化配置。
有關配置選項的完整列表,請參閱 SpringApplication API 文件。
流暢的構建器 API
如果您需要構建 ApplicationContext 層次結構(具有父/子關係的多個上下文),或者如果您更喜歡使用流暢的構建器 API,則可以使用 SpringApplicationBuilder。
SpringApplicationBuilder 允許您將多個方法呼叫鏈式連線起來,幷包含 parent 和 child 方法,讓您建立層次結構,如下例所示
-
Java
-
Kotlin
new SpringApplicationBuilder().sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
SpringApplicationBuilder()
.sources(Parent::class.java)
.child(Application::class.java)
.bannerMode(Banner.Mode.OFF)
.run(*args)
在建立 ApplicationContext 層次結構時存在一些限制。例如,Web 元件必須包含在子上下文中,並且父子上下文使用相同的 Environment。有關完整詳細資訊,請參閱 SpringApplicationBuilder API 文件。 |
應用程式可用性
當部署在平臺上時,應用程式可以使用 Kubernetes 探針等基礎設施向平臺提供有關其可用性的資訊。Spring Boot 提供了對常用“活躍度(liveness)”和“就緒度(readiness)”可用性狀態的開箱即用支援。如果您正在使用 Spring Boot 的“執行器”支援,那麼這些狀態會作為健康端點組暴露。
此外,您還可以透過將 ApplicationAvailability 介面注入到您自己的 bean 中來獲取可用性狀態。
活躍度狀態
應用程式的“活躍度”狀態表示其內部狀態是否允許其正常工作,或者在當前失敗時是否能夠自行恢復。“活躍度”狀態損壞意味著應用程式處於無法恢復的狀態,基礎設施應該重新啟動應用程式。
| 通常,“活躍度”狀態不應基於外部檢查,例如健康檢查。如果這樣做,一個失敗的外部系統(資料庫、Web API、外部快取)將觸發大規模重啟和整個平臺的級聯故障。 |
Spring Boot 應用程式的內部狀態主要由 Spring ApplicationContext 表示。如果應用程式上下文已成功啟動,Spring Boot 會假定應用程式處於有效狀態。一旦上下文重新整理完成,應用程式就被認為是活躍的,請參閱Spring Boot 應用程式生命週期和相關應用程式事件。
就緒度狀態
應用程式的“就緒度”狀態表示應用程式是否準備好處理流量。失敗的“就緒度”狀態告訴平臺目前不應將流量路由到該應用程式。這通常發生在啟動期間,同時 CommandLineRunner 和 ApplicationRunner 元件正在處理,或者在應用程式認為自己太忙而無法處理額外流量的任何時候。
一旦應用程式和命令列執行器被呼叫,應用程式就被認為是就緒的,請參閱Spring Boot 應用程式生命週期和相關應用程式事件。
預期在啟動期間執行的任務應由 CommandLineRunner 和 ApplicationRunner 元件執行,而不是使用 Spring 元件生命週期回撥,例如 @PostConstruct。 |
管理應用程式可用性狀態
應用程式元件可以透過注入 ApplicationAvailability 介面並呼叫其上的方法,隨時檢索當前的可用性狀態。更常見的是,應用程式會希望監聽狀態更新或更新應用程式的狀態。
例如,我們可以將應用程式的“就緒度”狀態匯出到一個檔案,以便 Kubernetes 的“exec Probe”可以檢視此檔案
-
Java
-
Kotlin
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyReadinessStateExporter {
@EventListener
public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC -> {
// create file /tmp/healthy
}
case REFUSING_TRAFFIC -> {
// remove file /tmp/healthy
}
}
}
}
import org.springframework.boot.availability.AvailabilityChangeEvent
import org.springframework.boot.availability.ReadinessState
import org.springframework.context.event.EventListener
import org.springframework.stereotype.Component
@Component
class MyReadinessStateExporter {
@EventListener
fun onStateChange(event: AvailabilityChangeEvent<ReadinessState>) {
when (event.state) {
ReadinessState.ACCEPTING_TRAFFIC -> {
// create file /tmp/healthy
}
ReadinessState.REFUSING_TRAFFIC -> {
// remove file /tmp/healthy
}
}
}
}
當應用程式損壞且無法恢復時,我們還可以更新應用程式的狀態
-
Java
-
Kotlin
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.LivenessState;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class MyLocalCacheVerifier {
private final ApplicationEventPublisher eventPublisher;
public MyLocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void checkLocalCache() {
try {
// ...
}
catch (CacheCompletelyBrokenException ex) {
AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);
}
}
}
import org.springframework.boot.availability.AvailabilityChangeEvent
import org.springframework.boot.availability.LivenessState
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Component
@Component
class MyLocalCacheVerifier(private val eventPublisher: ApplicationEventPublisher) {
fun checkLocalCache() {
try {
// ...
} catch (ex: CacheCompletelyBrokenException) {
AvailabilityChangeEvent.publish(eventPublisher, ex, LivenessState.BROKEN)
}
}
}
應用程式事件和監聽器
除了通常的 Spring 框架事件,例如 ContextRefreshedEvent,SpringApplication 還會發送一些額外的應用程式事件。
|
有些事件實際上是在 如果您希望這些監聽器自動註冊,無論應用程式是如何建立的,您可以在您的專案中新增一個
|
應用程式事件按以下順序傳送,隨著應用程式的執行
-
在執行開始時傳送
ApplicationStartingEvent,但在註冊監聽器和初始化器之外的任何處理之前。 -
當在上下文中使用的
Environment已知但在上下文建立之前,傳送ApplicationEnvironmentPreparedEvent。 -
當
ApplicationContext準備好並且 ApplicationContextInitializers 已被呼叫但任何 bean 定義尚未載入之前,傳送ApplicationContextInitializedEvent。 -
在重新整理開始之前,但在 bean 定義載入之後,傳送
ApplicationPreparedEvent。 -
在上下文重新整理之後,但在任何應用程式和命令列執行器被呼叫之前,傳送
ApplicationStartedEvent。 -
緊接著傳送一個
AvailabilityChangeEvent,其中包含LivenessState.CORRECT,表示應用程式被認為是活躍的。 -
在任何應用程式和命令列執行器被呼叫之後,傳送
ApplicationReadyEvent。 -
緊接著傳送一個
AvailabilityChangeEvent,其中包含ReadinessState.ACCEPTING_TRAFFIC,表示應用程式已準備好處理請求。 -
如果在啟動時出現異常,則傳送
ApplicationFailedEvent。
上述列表僅包含與 SpringApplication 相關的 SpringApplicationEvent。除了這些事件之外,在 ApplicationPreparedEvent 之後和 ApplicationStartedEvent 之前還會發布以下事件
-
在
WebServer就緒後傳送WebServerInitializedEvent。ServletWebServerInitializedEvent和ReactiveWebServerInitializedEvent分別是 Servlet 和 Reactive 變體。 -
當
ApplicationContext重新整理時,傳送ContextRefreshedEvent。
| 您通常不需要使用應用程式事件,但瞭解它們的存在會很有用。在內部,Spring Boot 使用事件來處理各種任務。 |
| 事件監聽器不應執行可能耗時的任務,因為它們預設在同一執行緒中執行。請考慮改用應用程式和命令列執行器。 |
應用程式事件透過使用 Spring Framework 的事件釋出機制傳送。該機制的一部分確保釋出到子上下文中的監聽器的事件也會發布到任何祖先上下文中的監聽器。因此,如果您的應用程式使用 SpringApplication 例項的層次結構,監聽器可能會收到相同型別應用程式事件的多個例項。
為了讓您的監聽器能夠區分其上下文的事件和後代上下文的事件,它應該請求注入其應用程式上下文,然後將注入的上下文與事件的上下文進行比較。可以透過實現 ApplicationContextAware 或(如果監聽器是一個 bean)透過使用 @Autowired 來注入上下文。
Web 環境
SpringApplication 嘗試代表您建立正確型別的 ApplicationContext。用於確定 WebApplicationType 的演算法如下
-
如果存在 Spring MVC,則使用
AnnotationConfigServletWebServerApplicationContext -
如果 Spring MVC 不存在且 Spring WebFlux 存在,則使用
AnnotationConfigReactiveWebServerApplicationContext
這意味著如果您在同一個應用程式中同時使用 Spring MVC 和 Spring WebFlux 中的新 WebClient,則預設會使用 Spring MVC。您可以透過呼叫 setWebApplicationType(WebApplicationType) 輕鬆覆蓋此行為。
還可以透過呼叫 setApplicationContextFactory(…) 來完全控制使用的 ApplicationContext 型別。
在使用 JUnit 測試中的 SpringApplication 時,通常需要呼叫 setWebApplicationType(WebApplicationType.NONE)。 |
訪問應用程式引數
如果您需要訪問傳遞給 SpringApplication.run(…) 的應用程式引數,可以注入 ApplicationArguments bean。ApplicationArguments 介面提供了對原始 String[] 引數以及解析後的 option 和 non-option 引數的訪問,如下例所示
-
Java
-
Kotlin
import java.util.List;
import org.springframework.boot.ApplicationArguments;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
if (debug) {
System.out.println(files);
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
import org.springframework.boot.ApplicationArguments
import org.springframework.stereotype.Component
@Component
class MyBean(args: ApplicationArguments) {
init {
val debug = args.containsOption("debug")
val files = args.nonOptionArgs
if (debug) {
println(files)
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
Spring Boot 還會在 Spring Environment 中註冊一個 CommandLinePropertySource。這讓您也可以使用 @Value 註解注入單個應用程式引數。 |
使用 ApplicationRunner 或 CommandLineRunner
如果需要在 SpringApplication 啟動後執行一些特定的程式碼,您可以實現 ApplicationRunner 或 CommandLineRunner 介面。這兩個介面的工作方式相同,都提供了一個 run 方法,該方法在 SpringApplication.run(…) 完成之前被呼叫。
| 此契約非常適合在應用程式啟動後但在開始接受流量之前執行的任務。 |
CommandLineRunner 介面以字串陣列形式提供對應用程式引數的訪問,而 ApplicationRunner 使用前面討論的 ApplicationArguments 介面。以下示例展示了一個帶有 run 方法的 CommandLineRunner
-
Java
-
Kotlin
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// Do something...
}
}
import org.springframework.boot.CommandLineRunner
import org.springframework.stereotype.Component
@Component
class MyCommandLineRunner : CommandLineRunner {
override fun run(vararg args: String) {
// Do something...
}
}
如果定義了多個 CommandLineRunner 或 ApplicationRunner bean 並且必須以特定順序呼叫,您可以另外實現 Ordered 介面或使用 Order 註解。
應用程式退出
每個 SpringApplication 都會向 JVM 註冊一個關閉鉤子,以確保 ApplicationContext 在退出時優雅地關閉。所有標準的 Spring 生命週期回撥(例如 DisposableBean 介面或 @PreDestroy 註解)都可以使用。
此外,bean 可以實現 ExitCodeGenerator 介面,如果它們希望在呼叫 SpringApplication.exit() 時返回特定的退出碼。然後,此退出碼可以傳遞給 System.exit() 以將其作為狀態碼返回,如下例所示
-
Java
-
Kotlin
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class MyApplication {
@Bean
public ExitCodeGenerator exitCodeGenerator() {
return () -> 42;
}
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(MyApplication.class, args)));
}
}
import org.springframework.boot.ExitCodeGenerator
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import kotlin.system.exitProcess
@SpringBootApplication
class MyApplication {
@Bean
fun exitCodeGenerator() = ExitCodeGenerator { 42 }
}
fun main(args: Array<String>) {
exitProcess(SpringApplication.exit(
runApplication<MyApplication>(*args)))
}
此外,ExitCodeGenerator 介面可以由異常實現。當遇到此類異常時,Spring Boot 會返回由實現的 getExitCode() 方法提供的退出碼。
如果存在多個 ExitCodeGenerator,則使用生成的第一個非零退出碼。要控制生成器呼叫的順序,可以另外實現 Ordered 介面或使用 Order 註解。
管理功能
可以透過指定 spring.application.admin.enabled 屬性來啟用應用程式的管理相關功能。這會將 SpringApplicationAdminMXBean 暴露在平臺 MBeanServer 上。您可以使用此功能遠端管理您的 Spring Boot 應用程式。此功能對於任何服務包裝器實現也可能很有用。
如果您想知道應用程式正在哪個 HTTP 埠上執行,請獲取鍵為 local.server.port 的屬性。 |
應用程式啟動跟蹤
在應用程式啟動期間,SpringApplication 和 ApplicationContext 執行許多與應用程式生命週期、bean 生命週期甚至處理應用程式事件相關的任務。藉助 ApplicationStartup,Spring Framework 允許您使用 StartupStep 物件跟蹤應用程式啟動序列。此資料可以用於分析目的,或者只是為了更好地瞭解應用程式的啟動過程。
您可以在設定 SpringApplication 例項時選擇一個 ApplicationStartup 實現。例如,要使用 BufferingApplicationStartup,您可以這樣編寫
-
Java
-
Kotlin
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
}
}
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup
import org.springframework.boot.runApplication
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args) {
applicationStartup = BufferingApplicationStartup(2048)
}
}
Spring Framework 提供了第一個可用的實現 FlightRecorderApplicationStartup。它將 Spring 特定的啟動事件新增到 Java Flight Recorder 會話中,旨在分析應用程式並將其 Spring 上下文生命週期與 JVM 事件(如分配、GC、類載入等)關聯起來。配置完成後,您可以透過啟用 Flight Recorder 執行應用程式來記錄資料
$ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
Spring Boot 附帶了 BufferingApplicationStartup 變體;此實現旨在緩衝啟動步驟並將其排入外部指標系統。應用程式可以在任何元件中請求型別為 BufferingApplicationStartup 的 bean。
Spring Boot 還可以配置為暴露一個 startup 端點,該端點將此資訊作為 JSON 文件提供。
虛擬執行緒
虛擬執行緒需要 Java 21 或更高版本。為了獲得最佳體驗,強烈建議使用 Java 24 或更高版本。要啟用虛擬執行緒,請將 spring.threads.virtual.enabled 屬性設定為 true。
在為您的應用程式啟用此選項之前,您應該考慮閱讀官方 Java 虛擬執行緒文件。在某些情況下,應用程式可能會因為“固定虛擬執行緒”而導致吞吐量降低;此頁面還解釋瞭如何使用 JDK Flight Recorder 或 jcmd CLI 檢測此類情況。
| 如果啟用了虛擬執行緒,配置執行緒池的屬性將不再起作用。這是因為虛擬執行緒是在 JVM 範圍內的平臺執行緒池上排程的,而不是在專用的執行緒池上。 |
虛擬執行緒的一個副作用是它們是守護執行緒。如果 JVM 的所有執行緒都是守護執行緒,JVM 將退出。當您依賴 @Scheduled bean 來保持應用程式執行等情況時,這種行為可能會成為問題。如果您使用虛擬執行緒,排程器執行緒是一個虛擬執行緒,因此也是一個守護執行緒,不會保持 JVM 執行。這不僅影響排程,也可能發生在其他技術中。為了在所有情況下保持 JVM 執行,建議將屬性 spring.main.keep-alive 設定為 true。這確保了即使所有執行緒都是虛擬執行緒,JVM 也能保持執行。 |