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.4)
2026-03-19T11:14:29.326Z INFO 128933 --- [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 25.0.2 with PID 128933 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2026-03-19T11:14:29.374Z INFO 128933 --- [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2026-03-19T11:14:32.409Z INFO 128933 --- [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2026-03-19T11:14:32.464Z INFO 128933 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2026-03-19T11:14:32.464Z INFO 128933 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.18]
2026-03-19T11:14:32.603Z INFO 128933 --- [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 2986 ms
2026-03-19T11:14:33.904Z INFO 128933 --- [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2026-03-19T11:14:33.922Z INFO 128933 --- [ main] o.s.b.d.f.logexample.MyApplication : Started MyApplication in 6.485 seconds (process running for 7.748)
2026-03-19T11:14:33.956Z INFO 128933 --- [ionShutdownHook] o.s.boot.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2026-03-19T11:14:33.975Z INFO 128933 --- [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属性启用延迟初始化,如下例所示:
-
Properties
-
YAML
spring.main.lazy-initialization=true
spring:
main:
lazy-initialization: true
如果希望在应用程序其余部分启用延迟初始化的同时,为某些 Bean 禁用延迟初始化,则可以使用 @Lazy 注解将这些 Bean 的 lazy 属性显式设置为 false。 |
自定义横幅
启动时显示的横幅可通过在类路径中添加一个 banner.txt 文件,或通过设置 spring.banner.location 属性指定该文件的位置来更改。
如果该文件的编码不是 UTF-8,您可以设置 spring.banner.charset。
在您的 banner.txt 文件中,您可以使用 Environment 中提供的任意键,以及以下任意占位符:
| 变量 | 描述 |
|---|---|
|
您应用程序的版本号,如 |
|
您的应用程序版本号,该版本号在 |
|
您正在使用的 Spring Boot 版本。
例如 |
|
您正在使用的 Spring Boot 版本,已格式化为显示格式(用方括号括起,并以 |
|
其中 |
|
您的应用程序标题,如在 |
如果希望以编程方式生成横幅,则可使用 SpringApplication.setBanner(…) 方法。
请使用 Banner 接口,并自行实现 printBanner() 方法。 |
您还可以使用 spring.main.banner-mode 属性来确定横幅是否需在 System.out(console)上打印、发送至已配置的日志记录器(log),或完全不生成(off)。
打印的横幅作为单例 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 开箱即用地支持常用的“存活”和“就绪”两种可用性状态。 如果您使用了 Spring Boot 的“执行器(actuator)”功能,则这些状态将作为健康端点组对外暴露。
此外,您还可以通过将 ApplicationAvailability 接口注入到您自己的 Bean 中来获取可用性状态。
存活状态
应用程序的“存活”(Liveness)状态表明其内部状态是否允许其正常工作,或在当前发生故障时能否自行恢复。 “存活”状态异常意味着应用程序已处于无法自行恢复的状态,此时基础设施应重启该应用程序。
| 通常,“存活”(Liveness)状态不应依赖于外部检查,例如 健康检查。 如果依赖外部检查,则外部系统(如数据库、Web API 或外部缓存)发生故障时,将触发大规模重启,并在平台范围内引发级联故障。 |
Spring Boot 应用程序的内部状态主要由 Spring ApplicationContext 表示。
如果应用上下文已成功启动,Spring Boot 即认为该应用程序处于有效状态。
一旦上下文刷新完成,应用程序即被视为处于活动状态,参见 Spring Boot 应用程序生命周期及相关应用事件。
就绪状态
应用程序的“就绪”(Readiness)状态表示该应用程序是否已准备好处理流量。
“就绪”状态失败时,平台会得知当前不应将流量路由至该应用程序。
这种情况通常发生在应用启动期间(例如正在处理 CommandLineRunner 和 ApplicationRunner 组件时),或在应用判定自身负载过重、无法处理额外流量的任何时刻。
一旦应用程序运行器(application runner)和命令行运行器(command-line runner)已被调用,应用程序即被视为已就绪。参见 Spring Boot 应用程序生命周期及相关应用事件。
预期在启动期间运行的任务应由 CommandLineRunner 和 ApplicationRunner 组件执行,而不应使用 Spring 组件生命周期回调(例如 @PostConstruct)。 |
管理应用程序可用性状态
应用程序组件可通过注入ApplicationAvailability接口并调用其方法,在任意时刻获取当前可用性状态。
更常见的情况是,应用程序希望监听状态更新或更新应用程序自身的状态。
例如,我们可以将应用程序的“就绪”(Readiness)状态导出到一个文件中,以便 Kubernetes 的“exec 探针”(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 Boot 提供了基于执行器健康端点的 Kubernetes HTTP 探针,用于“存活”和“就绪”状态检查。 您可以在专门的章节中获取有关在 Kubernetes 上部署 Spring Boot 应用程序的更多指导。
应用事件与监听器
除了常规的 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 版本和响应式版本。 -
当刷新一个
ApplicationContext时,会发送一个ContextRefreshedEvent。
| 你通常无需使用应用事件,但了解它们的存在会很有帮助。 在内部,Spring Boot 使用事件来处理各种任务。 |
| 事件监听器不应执行可能耗时较长的任务,因为它们默认在同一线程中执行。 请考虑改用 应用程序和命令行运行器。 |
应用程序事件通过 Spring 框架的事件发布机制进行发送。
该机制的一部分确保:在子应用上下文中发布的事件,也会发布到任意祖先应用上下文中的监听器。
因此,如果您的应用程序使用了 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 希望在调用 SpringApplication.exit() 时返回特定的退出码,则可实现 ExitCodeGenerator 接口。
随后,该退出码可传递给 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 属性,为应用程序启用与管理相关的功能。
此举将在平台 MBeanServer 上公开 SpringApplicationAdminMXBean。
您可以利用此功能远程管理您的 Spring Boot 应用程序。
该功能对于任何服务包装器(service wrapper)实现也同样有用。
如果您想知道应用程序正在哪个HTTP端口上运行,请使用键 local.server.port 获取该属性。 |
应用程序启动跟踪
在应用程序启动期间,SpringApplication 和 ApplicationContext 会执行许多与应用程序生命周期、Bean 生命周期甚至应用程序事件处理相关的任务。
借助 ApplicationStartup,Spring 框架允许您使用 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)
}
}
首个可用的实现是 FlightRecorderApplicationStartup,由 Spring Framework 提供。
该实现为 Java Flight Recorder 会话添加了 Spring 特有的启动事件,旨在对应用程序进行性能分析,并将 Spring 上下文生命周期与 JVM 事件(例如对象分配、垃圾回收、类加载等)相关联。
配置完成后,您可通过启用 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 虚拟线程文档。
在某些情况下,由于“固定虚拟线程”(Pinned Virtual Threads),应用程序的吞吐量可能会降低;本页还介绍了如何使用 JDK Flight Recorder(JDK Flight Recorder)或 jcmd 命令行工具来检测此类情况。
| 如果启用了虚拟线程,则用于配置线程池的属性将不再生效。 这是因为虚拟线程是在 JVM 全局的平台线程池上进行调度的,而非在专用的线程池上调度。 |
虚拟线程的一个副作用是:它们属于守护线程(daemon threads)。
当 JVM 中所有线程均为守护线程时,JVM 将自动退出。
此行为可能引发问题——例如,当你依赖 @Scheduled 类型的 Bean 来维持应用程序运行时。
若使用虚拟线程,则调度器线程(scheduler thread)本身也是虚拟线程,因而属于守护线程,无法阻止 JVM 退出。
该问题不仅影响调度功能,其他技术中也可能出现类似情况。
为确保 JVM 在所有情况下均保持运行,建议将属性 spring.main.keep-alive 设置为 true。
此举可保证即使所有线程均为虚拟线程,JVM 仍能持续运行。 |