|
对于最新稳定版本,请使用 Spring Boot 4.0.4! |
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 :: (v3.5.12)
2026-03-19T11:41:47.396Z INFO 134494 --- [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 17.0.18 with PID 134494 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2026-03-19T11:41:47.415Z INFO 134494 --- [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2026-03-19T11:41:50.967Z INFO 134494 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2026-03-19T11:41:51.011Z INFO 134494 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2026-03-19T11:41:51.011Z INFO 134494 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.52]
2026-03-19T11:41:51.138Z INFO 134494 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2026-03-19T11:41:51.141Z INFO 134494 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3423 ms
2026-03-19T11:41:52.531Z INFO 134494 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2026-03-19T11:41:52.593Z INFO 134494 --- [ main] o.s.b.d.f.logexample.MyApplication : Started MyApplication in 6.648 seconds (process running for 7.492)
2026-03-19T11:41:52.625Z INFO 134494 --- [ionShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2026-03-19T11:41:52.660Z INFO 134494 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
默认情况下,会显示 INFO 级别的日志消息,包括一些相关的启动详情,例如启动应用程序的用户。
如果需要使用除 INFO 之外的日志级别,可以按照日志级别中所述进行设置。
应用程序版本是通过主应用程序类所在包的实现版本(implementation version)来确定的。
通过将 spring.main.log-startup-info 设置为 false,可以关闭启动信息的日志记录。
这也会同时关闭应用程序激活配置文件(active profiles)的日志记录。
要在启动期间添加额外的日志记录,您可以在 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(false) 注解显式设置这些 Bean 的 lazy 属性为 false。 |
自定义横幅
启动时打印的横幅可以通过在类路径中添加一个banner.txt文件来更改,或者通过设置spring.banner.location属性以指向此类文件的位置。
如果该文件的编码不是UTF-8,则可以设置spring.banner.charset。
在您的 banner.txt 文件中,您可以使用 Environment 中的任何键以及以下任何占位符:
| 变量 | <description> </description> |
|---|---|
|
您的应用版本号,如在 |
|
您的应用程序版本号,如在 |
|
您正在使用的 Spring Boot 版本。
例如 |
|
您正在使用的 Spring Boot 版本,格式化后用于显示(用括号包围,并以 |
|
其中 |
|
您的应用程序的标题,如在 |
如果您希望以编程方式生成横幅,可以使用 SpringApplication.setBanner(…) 方法。
请使用 Banner 接口并实现您自己的 printBanner() 方法。 |
您还可以使用 spring.main.banner-mode 属性来确定是否需要在 System.out(console)上打印横幅、发送到配置的日志记录器(log),还是完全不生成(off)。
打印的横幅被注册为一个单例bean,名称如下:springBootBanner。
|
要使用 |
自定义 SpringApplication
如果 SpringApplication 的默认设置不符合您的喜好,您可以创建一个本地实例并对其进行自定义。
例如,要关闭横幅,您可以编写:
-
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 的“actuator”功能,那么这些状态会作为健康端点组(health endpoint groups)对外暴露。
此外,您还可以通过将 ApplicationAvailability 接口注入到您自己的 Bean 中来获取可用性状态。
存活状态
应用程序的“存活”状态指示其内部状态是否允许它正确工作,或者在当前失败时能否自行恢复。 如果“存活”状态出现故障,则表示该应用程序处于无法自行恢复的状态,基础设施应当重启该应用。
| 通常,“存活状态”(Liveness)不应基于外部检查(例如健康检查)来判断。 否则,一旦某个外部系统(如数据库、Web API 或外部缓存)发生故障,就会在整个平台上引发大规模重启和级联故障。 |
Spring Boot 应用程序的内部状态主要由 Spring ApplicationContext 表示。
如果应用程序上下文已成功启动,Spring Boot 会假定应用程序处于有效状态。
一旦上下文被刷新,应用程序即被视为存活,请参阅 Spring Boot 应用程序生命周期及相关的应用程序事件。
就绪状态
应用程序的“就绪”状态表示该应用是否已准备好处理流量。
失败的“就绪”状态会告知平台暂时不应将流量路由到该应用。
这通常发生在启动期间,此时正在处理 CommandLineRunner 和 ApplicationRunner 组件,或者在应用决定其过于繁忙而无法承载额外流量的任何时刻发生。
一旦应用程序和命令行运行器(command-line runners)被调用,应用程序即被视为已就绪,详见Spring Boot 应用程序生命周期及相关 Application Events。
预期在启动期间运行的任务应由 CommandLineRunner 和 ApplicationRunner 组件执行,而不是使用 Spring 组件生命周期回调(例如 @PostConstruct)。 |
管理应用程序可用性状态
应用程序组件可以随时通过注入 ApplicationAvailability 接口并调用其方法来检索当前的可用性状态。
更多情况下,应用程序会希望监听状态更新或更新应用程序的状态。
例如,我们可以将应用的“就绪状态”导出到一个文件中,这样Kubernetes 的 "exec 端口检测" 可以查看这个文件:
-
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
}
else -> {
// ...
}
}
}
}
当应用程序出现故障且无法恢复时,我们也可以更新应用的状态:
-
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 提供 使用 Actuator 健康端点的 Kubernetes HTTP 探针“存活”和“就绪”。 您可以在专门的部分获得更多关于 在 Kubernetes 上部署 Spring Boot 应用程序 的指导。
应用程序事件与监听器
除了常规的 Spring Framework 事件(例如 ContextRefreshedEvent)之外,SpringApplication 还会发送一些额外的应用事件。
|
某些事件实际上是在 如果您希望这些监听器无论应用程序如何创建都能自动注册,可以在项目中添加一个
|
应用事件按照以下顺序发送,当您的应用程序运行时:
-
在运行开始时,但在任何处理之前(除了监听器和初始化器的注册),会发送一个
ApplicationStartingEvent。 -
当上下文中要使用的
Environment已知但上下文尚未创建时,会发送一个ApplicationEnvironmentPreparedEvent。 -
当
ApplicationContext准备完毕且已调用 ApplicationContextInitializers,但在加载任何 bean 定义之前,会发送一个ApplicationContextInitializedEvent。 -
一个
ApplicationPreparedEvent会在刷新启动之前但 Bean 定义加载之后发送。 -
在上下文刷新之后,但在调用任何应用程序和命令行运行器之前,会发送一个
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 应用程序。
此功能对于任何服务包装器实现也可能非常有用。
如果要了解应用程序正在运行的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)
}
}
第一个可用的实现 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虚拟线程文档:这里。
在某些情况下,应用程序可能会因为“绑定虚拟线程”而经历较低的吞吐量;此页面还解释了如何使用JDK Flight Recorder或jcmd命令行界面来检测此类情况。
| 如果启用了虚拟线程,配置线程池的属性将不再生效。 这是因为虚拟线程会被调度到JVM范围内的平台线程池中,而不是专用线程池。 |
虚拟线程的一个副作用是它们是守护线程。
如果 JVM 的所有线程都是守护线程,JVM 将会退出。
当你依赖 @Scheduled Bean(例如)来保持应用程序运行时,这种行为可能会成为问题。
如果你使用虚拟线程,调度器线程将是一个虚拟线程,因此也是一个守护线程,无法保持 JVM 运行。
这不仅影响调度,其他技术也可能出现类似情况。
为了在所有情况下保持 JVM 运行,建议将属性 spring.main.keep-alive 设置为 true。
这样可以确保即使所有线程都是虚拟线程,JVM 也能保持运行状态。 |