此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.3.4! |
该类提供了一种便捷的方法来引导从方法启动的 Spring 应用程序。
在许多情况下,您可以委托给 static 方法,如以下示例所示:SpringApplication
main()
SpringApplication.run
-
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.4.0-SNAPSHOT)
2024-10-04T13:31:49.282Z INFO 83530 --- [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 17.0.12 with PID 83530 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2024-10-04T13:31:49.300Z INFO 83530 --- [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2024-10-04T13:31:51.984Z INFO 83530 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2024-10-04T13:31:52.002Z INFO 83530 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-10-04T13:31:52.003Z INFO 83530 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.30]
2024-10-04T13:31:52.075Z INFO 83530 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-10-04T13:31:52.077Z INFO 83530 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2518 ms
2024-10-04T13:31:53.392Z INFO 83530 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2024-10-04T13:31:53.427Z INFO 83530 --- [ main] o.s.b.d.f.logexample.MyApplication : Started MyApplication in 5.607 seconds (process running for 6.373)
2024-10-04T13:31:53.456Z INFO 83530 --- [ionShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
2024-10-04T13:31:53.493Z INFO 83530 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
默认情况下,将显示日志记录消息,包括一些相关的启动详细信息,例如启动应用程序的用户。
如果您需要的日志级别不是 ,则可以设置它,如 Log Levels 中所述。
应用程序版本是使用主应用程序类的包中的实现版本确定的。
可以通过设置为 来关闭启动信息记录。
这还将关闭应用程序活动配置文件的日志记录。INFO
INFO
spring.main.log-startup-info
false
要在启动期间添加其他日志记录,可以在 的子类中覆盖。logStartupInfo(boolean) SpringApplication |
要在启动期间添加其他日志记录,可以在 的子类中覆盖。logStartupInfo(boolean) SpringApplication |
启动失败
如果您的应用程序无法启动,注册后将有机会提供专用错误消息和解决问题的具体操作。
例如,如果您在 port 上启动一个 Web 应用程序,并且该端口已在使用中,您应该会看到类似于以下消息的内容:FailureAnalyzers
8080
***************************
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
属性或为 .
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
例如,如果您使用 运行应用程序,则可以按如下方式启用该属性:java -jar
debug
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
Spring Boot 提供了许多实现,您可以添加自己的实现。FailureAnalyzer |
延迟初始化
SpringApplication
允许延迟初始化应用程序。
启用延迟初始化后,将根据需要创建 bean,而不是在应用程序启动期间创建 bean。
因此,启用延迟初始化可以减少应用程序启动所需的时间。
在 Web 应用程序中,启用延迟初始化将导致许多与 Web 相关的 bean 在收到 HTTP 请求之前不会初始化。
延迟初始化的一个缺点是,它可能会延迟发现应用程序的问题。 如果延迟初始化了配置错误的 bean,则在启动期间将不再发生失败,并且只有在初始化 bean 时问题才会变得明显。 还必须注意确保 JVM 具有足够的内存来容纳应用程序的所有 bean,而不仅仅是在启动期间初始化的 bean。 由于这些原因,默认情况下不启用延迟初始化,建议在启用延迟初始化之前对 JVM 的堆大小进行微调。
可以使用 on 或 on 方法以编程方式启用延迟初始化。
或者,可以使用以下示例中所示的属性启用它:lazyInitialization
SpringApplicationBuilder
setLazyInitialization
SpringApplication
spring.main.lazy-initialization
-
Properties
-
YAML
spring.main.lazy-initialization=true
spring:
main:
lazy-initialization: true
如果要对某些 bean 禁用延迟初始化,同时对应用程序的其余部分使用延迟初始化,则可以使用 Comments 将其 lazy 属性显式设置为 false。@Lazy(false) |
如果要对某些 bean 禁用延迟初始化,同时对应用程序的其余部分使用延迟初始化,则可以使用 Comments 将其 lazy 属性显式设置为 false。@Lazy(false) |
自定义横幅
可以通过将文件添加到 Classpath 或将属性设置为此类文件的位置来更改启动时打印的标题。
如果文件的编码不是 UTF-8,则可以设置 .banner.txt
spring.banner.location
spring.banner.charset
在文件中,您可以使用 中的任何可用键以及以下任何占位符:banner.txt
Environment
变量 | 描述 |
---|---|
|
应用程序中声明的应用程序版本号 。
例如,打印为 。 |
|
应用程序的版本号,在 中声明并格式化为显示(用括号括起来,前缀为 )。
例如。 |
|
您正在使用的 Spring Boot 版本。
例如。 |
|
您正在使用的 Spring Boot 版本,格式化为显示(用括号括起来,前缀为 )。
例如。 |
|
其中 是 ANSI 转义码的名称。
有关详细信息,请参阅。 |
|
应用程序中声明的应用程序标题。
例如,打印为 . |
如果要以编程方式生成横幅,可以使用该方法。
使用该接口并实现您自己的方法。SpringApplication.setBanner(…) org.springframework.boot.Banner printBanner() |
您还可以使用该属性来确定横幅是否必须打印在 () 上、发送到配置的记录器 () 或根本不生成 ()。spring.main.banner-mode
System.out
console
log
off
打印的横幅将注册为以下名称下的单例 Bean: 。springBootBanner
这些 , 和 属性仅在您使用 Spring Boot Starters或与之一起使用时可用。
如果您运行的是解压缩的 jar 并使用本机映像启动它或将应用程序作为本机映像运行,则不会解析这些值。 要使用这些属性,请使用 |
变量 | 描述 |
---|---|
|
应用程序中声明的应用程序版本号 。
例如,打印为 。 |
|
应用程序的版本号,在 中声明并格式化为显示(用括号括起来,前缀为 )。
例如。 |
|
您正在使用的 Spring Boot 版本。
例如。 |
|
您正在使用的 Spring Boot 版本,格式化为显示(用括号括起来,前缀为 )。
例如。 |
|
其中 是 ANSI 转义码的名称。
有关详细信息,请参阅。 |
|
应用程序中声明的应用程序标题。
例如,打印为 . |
如果要以编程方式生成横幅,可以使用该方法。
使用该接口并实现您自己的方法。SpringApplication.setBanner(…) org.springframework.boot.Banner printBanner() |
这些 , 和 属性仅在您使用 Spring Boot Starters或与之一起使用时可用。
如果您运行的是解压缩的 jar 并使用本机映像启动它或将应用程序作为本机映像运行,则不会解析这些值。 要使用这些属性,请使用 |
自定义 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)
}
}
传递给的构造函数参数是 Spring bean 的配置源。
在大多数情况下,这些是对类的引用,但它们也可以是直接引用类。SpringApplication @Configuration @Component |
也可以使用文件进行配置。
有关详细信息,请参阅 外部化配置 。SpringApplication
application.properties
有关配置选项的完整列表,请参阅 API 文档。SpringApplication
传递给的构造函数参数是 Spring bean 的配置源。
在大多数情况下,这些是对类的引用,但它们也可以是直接引用类。SpringApplication @Configuration @Component |
Fluent Builder API
如果您需要构建层次结构(具有父/子关系的多个上下文),或者您更喜欢使用 Fluent 构建器 API,则可以使用 .ApplicationContext
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)
创建层次结构时存在一些限制。
例如,Web 组件必须包含在子上下文中,并且父上下文和子上下文都使用相同的 Web 组件。
请参阅 API 文档 了解完整详细信息。ApplicationContext Environment SpringApplicationBuilder |
创建层次结构时存在一些限制。
例如,Web 组件必须包含在子上下文中,并且父上下文和子上下文都使用相同的 Web 组件。
请参阅 API 文档 了解完整详细信息。ApplicationContext Environment SpringApplicationBuilder |
应用程序可用性
在平台上部署时,应用程序可以使用 Kubernetes 探针等基础设施向平台提供有关其可用性的信息。 Spring Boot 包括对常用的“liveness”和“readiness”可用性状态的开箱即用支持。 如果您使用的是 Spring Boot 的“actuator”支持,则这些状态将作为运行状况端点组公开。
此外,您还可以通过将接口注入到您自己的 bean 中来获取可用性状态。ApplicationAvailability
活动状态
应用程序的 “Liveness” 状态表明其内部状态是否允许它正常工作,或者如果当前出现故障,则自行恢复。 损坏的 “Liveness” 状态意味着应用程序处于无法恢复的状态,基础设施应重新启动应用程序。
通常,“Liveness” 状态不应基于外部检查,例如运行状况检查。 如果是这样,则失败的外部系统(数据库、Web API、外部缓存)将在整个平台上触发大规模重启和级联故障。 |
Spring Boot 应用程序的内部状态主要由 Spring 表示。
如果应用程序上下文已成功启动,则 Spring Boot 假定应用程序处于有效状态。
一旦刷新了上下文,应用程序就被视为活动了,请参阅 Spring Boot 应用程序生命周期和相关应用程序事件。ApplicationContext
就绪状态
应用程序的 “Readiness” 状态表明应用程序是否已准备好处理流量。
失败的 “Readiness” 状态告诉平台它暂时不应将流量路由到应用程序。
这通常发生在启动期间、处理组件时,或者如果应用程序决定太忙而无法进行其他流量,则随时发生。CommandLineRunner
ApplicationRunner
一旦调用了应用程序和命令行运行器,应用程序就被视为准备就绪,请参阅 Spring Boot 应用程序生命周期和相关应用程序事件。
预期在启动期间运行的任务应由 and 组件执行,而不是使用 Spring 组件生命周期回调,例如 .CommandLineRunner ApplicationRunner @PostConstruct |
管理应用程序可用性状态
应用程序组件可以随时通过注入接口并对其调用方法来检索当前可用性状态。
更常见的是,应用程序需要侦听状态更新或更新应用程序的状态。ApplicationAvailability
例如,我们可以将应用程序的 “Readiness” 状态导出到一个文件中,以便 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
}
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)
}
}
}
通常,“Liveness” 状态不应基于外部检查,例如运行状况检查。 如果是这样,则失败的外部系统(数据库、Web API、外部缓存)将在整个平台上触发大规模重启和级联故障。 |
预期在启动期间运行的任务应由 and 组件执行,而不是使用 Spring 组件生命周期回调,例如 .CommandLineRunner ApplicationRunner @PostConstruct |
应用程序事件和侦听器
除了通常的 Spring Framework 事件(例如 )之外,a 还会发送一些其他应用程序事件。ContextRefreshedEvent
SpringApplication
某些事件实际上是在创建 之前触发的,因此您无法在这些事件上将侦听器注册为 。
您可以使用 method 或 method 注册它们。 如果您希望自动注册这些侦听器,而不管应用程序是如何创建的,您都可以将文件添加到项目中并使用 key 引用您的侦听器,如以下示例所示:
|
应用程序事件在应用程序运行时按以下顺序发送:
-
An 在运行开始时发送,但在任何处理之前发送,侦听器和初始值设定项的注册除外。
ApplicationStartingEvent
-
当 要在上下文中使用的 已知但在创建上下文之前,将发送 An。
ApplicationEnvironmentPreparedEvent
Environment
-
当准备好并调用ApplicationContextInitializers时,但在加载任何 bean 定义之前,将发送一个。
ApplicationContextInitializedEvent
ApplicationContext
-
在刷新开始之前,但在加载 Bean 定义之后发送 AN。
ApplicationPreparedEvent
-
在刷新上下文之后,但在调用任何应用程序和命令行运行程序之前发送 AN。
ApplicationStartedEvent
-
An 紧随其后发送 with,以指示应用程序被视为实时应用程序。
AvailabilityChangeEvent
LivenessState.CORRECT
-
在调用任何应用程序和命令行运行程序后发送 AN。
ApplicationReadyEvent
-
An 紧随其后发送 with,以指示应用程序已准备好为请求提供服务。
AvailabilityChangeEvent
ReadinessState.ACCEPTING_TRAFFIC
-
如果启动时出现异常,则发送 An。
ApplicationFailedEvent
上面的列表仅包含绑定到 .
除此之外,以下事件还会在 之后 和 之前发布 :SpringApplicationEvent
SpringApplication
ApplicationPreparedEvent
ApplicationStartedEvent
-
A 在 准备就绪后发送。 和 分别是 servlet 和 reactive 变体。
WebServerInitializedEvent
WebServer
ServletWebServerInitializedEvent
ReactiveWebServerInitializedEvent
-
刷新 时发送 A。
ContextRefreshedEvent
ApplicationContext
您通常不需要使用应用程序事件,但知道它们存在会很方便。 在内部, Spring Boot 使用事件来处理各种任务。 |
事件侦听器不应运行可能很长的任务,因为它们默认在同一线程中执行。 请考虑改用应用程序和命令行运行程序。 |
应用程序事件是使用 Spring Framework 的事件发布机制发送的。
此机制的一部分可确保发布到子上下文中的侦听器的事件也发布到任何祖先上下文中的侦听器。
因此,如果您的应用程序使用实例层次结构,则侦听器可能会接收相同类型应用程序事件的多个实例。SpringApplication
要使侦听器能够区分其上下文的事件和后代上下文的事件,它应请求注入其应用程序上下文,然后将注入的上下文与事件的上下文进行比较。
可以通过实现来注入上下文,或者,如果侦听器是 bean,则通过使用 。ApplicationContextAware
@Autowired
某些事件实际上是在创建 之前触发的,因此您无法在这些事件上将侦听器注册为 。
您可以使用 method 或 method 注册它们。 如果您希望自动注册这些侦听器,而不管应用程序是如何创建的,您都可以将文件添加到项目中并使用 key 引用您的侦听器,如以下示例所示:
|
您通常不需要使用应用程序事件,但知道它们存在会很方便。 在内部, Spring Boot 使用事件来处理各种任务。 |
事件侦听器不应运行可能很长的任务,因为它们默认在同一线程中执行。 请考虑改用应用程序和命令行运行程序。 |
Web 环境
A 尝试代表您创建正确的 类型。
用于确定 a 的算法如下:SpringApplication
ApplicationContext
WebApplicationType
-
如果存在 Spring MVC,则使用
AnnotationConfigServletWebServerApplicationContext
-
如果 Spring MVC 不存在而 Spring WebFlux 存在,则使用
AnnotationConfigReactiveWebServerApplicationContext
-
否则,使用
AnnotationConfigApplicationContext
这意味着,如果你在同一个应用程序中使用 Spring MVC 和 Spring WebFlux 中的新版本,则默认情况下将使用 Spring MVC。
您可以通过调用 .WebClient
setWebApplicationType(WebApplicationType)
还可以通过调用 .ApplicationContext
setApplicationContextFactory(…)
在 JUnit 测试中使用时,通常需要调用 Call。setWebApplicationType(WebApplicationType.NONE) SpringApplication |
在 JUnit 测试中使用时,通常需要调用 Call。setWebApplicationType(WebApplicationType.NONE) SpringApplication |
访问应用程序参数
如果需要访问传递给 的应用程序参数,则可以注入一个 bean。
该接口提供对原始参数以及 parsed 和 arguments 的访问,如以下示例所示:SpringApplication.run(…)
org.springframework.boot.ApplicationArguments
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 注册 a 。
这还允许您使用 annotation 注入单个应用程序参数。CommandLinePropertySource Environment @Value |
Spring Boot 还向 Spring 注册 a 。
这还允许您使用 annotation 注入单个应用程序参数。CommandLinePropertySource Environment @Value |
使用 ApplicationRunner 或 CommandLineRunner
如果你需要在启动后运行一些特定的代码,你可以实现 or 接口。
这两个接口的工作方式相同,并提供单个方法,该方法在完成之前调用。SpringApplication
ApplicationRunner
CommandLineRunner
run
SpringApplication.run(…)
此协定非常适合应在应用程序启动之后但在开始接受流量之前运行的任务。 |
接口以字符串数组的形式提供对应用程序参数的访问,而 则使用前面讨论的接口。
以下示例显示了 with a 方法:CommandLineRunner
ApplicationRunner
ApplicationArguments
CommandLineRunner
run
-
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...
}
}
如果定义了多个 或 bean,并且必须按特定 Sequences 调用,则还可以实现接口或使用 Comments。CommandLineRunner
ApplicationRunner
org.springframework.core.Ordered
org.springframework.core.annotation.Order
此协定非常适合应在应用程序启动之后但在开始接受流量之前运行的任务。 |
应用程序退出
每个 API 都会向 JVM 注册一个 shutdown 钩子,以确保 在退出时正常关闭。
可以使用所有标准的 Spring 生命周期回调(例如接口或 Comments)。SpringApplication
ApplicationContext
DisposableBean
@PreDestroy
此外,如果 bean 希望在调用时返回特定的退出代码,则可以实现该接口。
然后,可以将此退出代码传递给 以将其作为状态代码返回,如以下示例所示:org.springframework.boot.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)))
}
此外,该接口可能由异常实现。
当遇到此类异常时, Spring Boot 返回已实现的方法提供的退出代码。ExitCodeGenerator
getExitCode()
如果有多个 ,则使用生成的第一个非零退出代码。
要控制生成器的调用顺序,请另外实现接口或使用 Comments。ExitCodeGenerator
org.springframework.core.Ordered
org.springframework.core.annotation.Order
管理员功能
可以通过指定属性为应用程序启用与管理员相关的功能。
这将在平台上公开 。
您可以使用此功能远程管理 Spring Boot 应用程序。
此功能对于任何服务包装器实现也很有用。spring.application.admin.enabled
SpringApplicationAdminMXBean
MBeanServer
如果您想知道应用程序正在哪个 HTTP 端口上运行,请获取键为 .local.server.port |
如果您想知道应用程序正在哪个 HTTP 端口上运行,请获取键为 .local.server.port |
应用程序启动跟踪
在应用程序启动期间,和 执行许多与应用程序生命周期相关的任务,
bean 生命周期,甚至处理应用程序事件。
使用 Spring Framework,您可以使用 StartupStep
对象跟踪应用程序启动序列。
收集此数据可以用于分析目的,或者只是为了更好地了解应用程序启动过程。SpringApplication
ApplicationContext
ApplicationStartup
您可以在设置实例时选择实施。
例如,要使用 ,您可以编写:ApplicationStartup
SpringApplication
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 提供。
它将特定于 Spring 的启动事件添加到 Java Flight Recorder 会话中,用于分析应用程序并将其 Spring 上下文生命周期与 JVM 事件(例如分配、GC、类加载等)相关联。
配置后,您可以通过在启用 Flight Recorder 的情况下运行应用程序来记录数据:FlightRecorderApplicationStartup
$ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
Spring Boot 附带了该变体;此实现用于缓冲启动步骤并将其排空到外部 Metrics 系统中。
应用程序可以在任何组件中请求 type 为 的 bean。BufferingApplicationStartup
BufferingApplicationStartup
Spring Boot 还可以配置为公开一个启动
端点,该端点将此信息作为 JSON 文档提供。
虚拟线程
如果您在 Java 21 或更高版本上运行,则可以通过将属性设置为 .spring.threads.virtual.enabled
true
在为您的应用程序启用此选项之前,您应该考虑阅读官方 Java 虚拟线程文档。
在某些情况下,由于“固定虚拟线程”,应用程序的吞吐量可能会降低;本页还介绍了如何使用 JDK Flight Recorder 或 CLI 检测此类情况。jcmd
如果启用了虚拟线程,则配置线程池的属性将不再有效。 这是因为虚拟线程被调度在 JVM 范围的平台线程池上,而不是在专用线程池上。 |
虚拟线程的一个副作用是它们是守护程序线程。
如果 JVM 的所有线程都是守护程序线程,则 JVM 将退出。
例如,当您依赖 bean 来保持应用程序活动状态时,此行为可能会成为一个问题。
如果使用虚拟线程,则调度程序线程是虚拟线程,因此是守护程序线程,不会使 JVM 保持活动状态。
这不仅会影响调度,其他技术也可能如此。
要使 JVM 在所有情况下都运行,建议将属性设置为 。
这可确保 JVM 保持活动状态,即使所有线程都是虚拟线程也是如此。@Scheduled spring.main.keep-alive true |
如果启用了虚拟线程,则配置线程池的属性将不再有效。 这是因为虚拟线程被调度在 JVM 范围的平台线程池上,而不是在专用线程池上。 |
虚拟线程的一个副作用是它们是守护程序线程。
如果 JVM 的所有线程都是守护程序线程,则 JVM 将退出。
例如,当您依赖 bean 来保持应用程序活动状态时,此行为可能会成为一个问题。
如果使用虚拟线程,则调度程序线程是虚拟线程,因此是守护程序线程,不会使 JVM 保持活动状态。
这不仅会影响调度,其他技术也可能如此。
要使 JVM 在所有情况下都运行,建议将属性设置为 。
这可确保 JVM 保持活动状态,即使所有线程都是虚拟线程也是如此。@Scheduled spring.main.keep-alive true |