[TOC] SpringApplication 是Spring Boot 提供的一个类,该类提供了一个便捷的方法引导Spring应用, 从应用的入口main() 方法启动应用, 主方法直接调用SpringApplication.run() 方法, 类似: ``` @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` 启动之后, 在控制台看到如下信息代表启动成功了。 ``` . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.5.0) 2021-11-24 07:01:30.951 INFO 1592 --- [ restartedMain] c.o.s.SpringbootEncyApplication : Starting SpringbootEncyApplication using Java 1.8.0_211 on LAPTOP-C6T2C3A5 with PID 1592 (D:\devworkspace\eclipse\springboot-ency\target\classes started by xuemi in D:\devworkspace\eclipse\springboot-ency) 2021-11-24 07:01:30.953 INFO 1592 --- [ restartedMain] c.o.s.SpringbootEncyApplication : No active profile set, falling back to default profiles: default 2021-11-24 07:01:30.992 INFO 1592 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable 2021-11-24 07:01:30.992 INFO 1592 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG' 2021-11-24 07:01:31.598 INFO 1592 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2021-11-24 07:01:31.666 INFO 1592 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 60 ms. Found 2 JPA repository interfaces. 2021-11-24 07:01:32.502 INFO 1592 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2021-11-24 07:01:32.512 INFO 1592 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2021-11-24 07:01:32.512 INFO 1592 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.46] 2021-11-24 07:01:32.726 INFO 1592 --- [ restartedMain] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 2021-11-24 07:01:32.731 INFO 1592 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2021-11-24 07:01:32.731 INFO 1592 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1738 ms 2021-11-24 07:01:32.819 INFO 1592 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-11-24 07:01:33.046 INFO 1592 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2021-11-24 07:01:33.052 INFO 1592 --- [ restartedMain] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:236bfaf5-4084-41ad-8985-f5c858eff903' 2021-11-24 07:01:33.234 INFO 1592 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2021-11-24 07:01:33.279 INFO 1592 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.31.Final 2021-11-24 07:01:33.401 INFO 1592 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} 2021-11-24 07:01:33.512 INFO 1592 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 2021-11-24 07:01:34.076 INFO 1592 --- [ restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2021-11-24 07:01:34.086 INFO 1592 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2021-11-24 07:01:34.150 WARN 1592 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 2021-11-24 07:01:35.020 INFO 1592 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2021-11-24 07:01:35.069 INFO 1592 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2021-11-24 07:01:35.078 INFO 1592 --- [ restartedMain] c.o.s.SpringbootEncyApplication : Started SpringbootEncyApplication in 4.466 seconds (JVM running for 4.96) ``` 默认情况下,控制台会显示 INFO 日志消息,包括一些相关的启动详细信息,例如启动应用程序的用户。 如果需要 INFO 以外的日志级别,可以进行设置,参考本系列的“4.日志”。 可以通过将 `spring.main.log-startup-info `设置为 false 来关闭启动信息记录。 提示: 要在启动期间添加额外的日志记录,您可以在 SpringApplication 的子类中覆盖 logStartupInfo(boolean)。 ## 1. 启动失败 如果应用启用失败, 注册`FailureAnalyzers`有机会获取更详细的错误信息和解决问题的方法。比如默认的8080端口被占用,会报如下错误信息: ``` Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2021-11-24 07:03:29.531 ERROR 13088 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. ``` 注意:Spring Boot 提供了许多 FailureAnalyzer 实现,也可以添加自己的。 如果没有错误分析器用来处理异常, 还是可以看到完整的报告来了解发生了什么错误, 只需要org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener 启用调试属性或启用调试日志记录。 比如: 如果使用java -jar 的方式运行应用程序, 则可以使用以下方式启动调试: `java -jar myproject-0.0.1-SNAPSHOT.jar --debug` ## 2. 懒初始化 SpringApplication支持应用程序的懒初始化。启用懒初始化之后,Bean会在需要的时候加载, 而不是在应用启动时加载。懒初始化的好处是可以缩短应用启动的时间。 在Web应用中,懒初始化会让很多Web相关的Bean 直到接受到http请求的时候才初始化。 延迟初始化的一个缺点是它会延迟发现应用程序的问题。 如果一个错误配置的 bean 被延迟初始化,那么在启动过程中将不再发生故障,并且只有在 bean 初始化时问题才会被发现。 还必须注意确保 JVM 有足够的内存来容纳所有应用程序的 bean,而不仅仅是那些在启动期间初始化的 bean。 由于这些原因,默认情况下不启用延迟初始化,建议在启用延迟初始化之前对 JVM 的堆大小进行微调。 懒初始化启用的方式: * 方式1: 配置属性: `spring.main.lazy-initialization=true` * 方式2: 代码: SpringApplicationBuilder 的lazyInitialization() * 方式3: 代码: SpringApplication 的setLazyInitialization() 提示: 如果设置了应用的延迟初始化, 但对于某些Bean又希望不延迟, 可以使用注解 `@Lazy(false)`。 ## 3. 自定义启动的横幅标志 Spring Boot 启动的时候在控制台会打印一个Spring的横幅标志(如本篇开头的介绍)。该横幅标志可以自行修改, 修改的方式有: * 在类路径添加 banner.txt 文件 * 也可以通过spring.banner.location设置文件位置 对于 非UTF-8编码的文件, 可以使用spring.banner.charset 设置字符集。 除了文本文件之外,也可以向类路径添加banner.gif、banner.jpg 或banner.png 图像文件,还可以设置spring.banner.image.location 属性。 图像被转换为 ASCII 艺术表现形式并打印。 在 banner.txt 文件中,可以使用以下占位符: | 变量 | 描述 | | --- | --- | | ${application.version} | 应用的版本号,在MANIFEST.MF文件中, 类似: Implementation-Version: 1.0 | |${application.formatted-version} | 应用程序的版本号,在 MANIFEST.MF 中声明并格式化以供显示(用括号括起来并以 v 为前缀)。 例如 (v1.0)。 | | ${spring-boot.version} | Spring Boot 版本, 比如 2.6.0 | | ${spring-boot.formatted-version} | Spring Boot 版本,已格式化以显示(用括号括起来并以 v 为前缀)。 例如 (v2.6.0) | |`${Ansi.NAME}`(or`${AnsiColor.NAME}`,`${AnsiBackground.NAME}`,`${AnsiStyle.NAME}`) | NAME 是 ANSI 转义码的名称 | | ${application.title} | 应用程序的标题,在 MANIFEST.MF 中声明。 例如,Implementation-Title: MyApp 打印为 MyApp。 | 提示: 以编程方式生成横幅,则可以使用 SpringApplication.setBanner(... ) 方法。 继承org.springframework.boot.Banner 接口并实现自己的 printBanner() 方法。 使用 spring.main.banner-mode 属性来控制横幅是否必须在 System.out(控制台)上打印,或是发送到配置的记录器(日志),或者根本不生成(关闭) 用来进行横幅打印的单例Bean的名字是 **springBootBanner**。 注意: ${application.version} 和 ${application.formatted-version} 属性仅在使用 Spring Boot 启动器时可用。 如果运行一个解压的 jar 并使用 java -cp <classpath> <mainclass> 启动它,这些值将不会被解析。 所以建议始终使用 java org.springframework.boot.loader.JarLauncher 启动解压的 jar。 这将在构建类路径和启动应用程序之前初始化 application.* 横幅变量。 ## 4. 自定义SpringApplication SpringApplication.run() 对应一个默认的SpringApplication实例, 也可以创建自己的SpringApplication实例并对其进行设置, 举例来看,要关闭启动的横幅,可以使用如下代码: ``` @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(MyApplication.class); application.setBannerMode(Banner.Mode.OFF); application.run(args); } } ``` 注意:传递给 SpringApplication 的构造函数参数是 Spring bean 的配置源。 在大多数情况下,这些是对@Configuration 类的引用,但它们也可以是对@Component 类的直接引用。 也可以使用 application.properties 文件配置 SpringApplication。详细可以参考 “2.配置外部化”。 ## 5. 流利的构建器 API 如果需要构建 ApplicationContext 层次结构(具有父/子关系的多个上下文),或者偏好使用“流畅”的构建器 API,则可以使用 SpringApplicationBuilder。 SpringApplicationBuilder 允许将多个方法调用链接在一起,并包含允许创建层次结构的父方法和子方法,如下所示: ``` new SpringApplicationBuilder() .sources(Parent.class) .child(Application.class) .run(args); ``` 注意: 创建 ApplicationContext 层次结构时有一些限制。 例如,Web 组件必须包含在子上下文中,并且对父上下文和子上下文使用相同的环境。 ## 6. 应用的可用性 在平台上部署时,应用程序可以使用 Kubernetes Probes 等基础设施向平台提供有关其可用性的信息。 Spring Boot 包括对常用“活跃”和“就绪”可用性状态的开箱即用支持。 如果使用 Spring Boot 的“actuator”支持,那么这些状态将作为健康端点组公开。 此外,还可以通过将 ApplicationAvailability 接口注入到自己的 bean 中来获取可用性状态。 #### 6.1 活跃状态(liveness) 应用程序的“活跃度”状态表明它的内部状态是否允许它正常工作,或者如果它当前失败则自行恢复。 损坏的“Liveness”状态意味着应用程序处于无法恢复的状态,基础设施应该重新启动应用程序。 注意: 一般来说,“Liveness”状态不应该基于外部检查,例如健康检查。 如果确实如此,则出现故障的外部系统(数据库、Web API、外部缓存)将触发整个平台的大规模重启和级联故障。 Spring Boot 应用程序的内部状态主要由 Spring ApplicationContext 表示。 如果应用程序上下文已成功启动,Spring Boot 会假定应用程序处于有效状态。 一旦上下文刷新,应用程序就被认为是活动的,可以参考 “1.7 应用事件和监听 ” 的介绍。 #### 6.2 就绪状态 (Readiness ) 应用程序的“就绪”状态表明应用程序是否已准备好处理流量。 失败的“就绪”状态告诉平台它现在不应将流量路由到应用程序。 这通常发生在启动期间,同时正在处理 CommandLineRunner 和 ApplicationRunner 组件,或者在应用程序确定它太忙而无法增加流量时的任何时间。 一旦应用程序和命令行运行程序被调用,应用程序就被认为已准备就绪,请参考 “1.7 应用事件和监听 ” 的介绍 提示:预期在启动期间运行的任务应该由 CommandLineRunner 和 ApplicationRunner 组件执行,而不是使用 Spring 组件生命周期回调,例如 @PostConstruct。 #### 6.3 管理应用程序可用性状态 通过注入 ApplicationAvailability 接口并在其上调用方法,应用程序组件可以随时检索当前的可用性状态。 更多的时候,应用程序会想要监听状态更新或更新应用程序的状态。 例如,可以将应用程序的“Readiness”状态导出到一个文件中,这样 Kubernetes 的“exec Probe”就可以查看这个文件: ``` @Component public class MyReadinessStateExporter { @EventListener public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) { switch (event.getState()) { case ACCEPTING_TRAFFIC: // create file /tmp/healthy break; case REFUSING_TRAFFIC: // remove file /tmp/healthy break; } } } ``` 还可以在应用程序中断且无法恢复时更新应用程序的状态: ``` @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); } } } ``` Spring Boot 通过 Actuator Health Endpoints 为“Liveness”和“Readiness”提供 Kubernetes HTTP 探测。 可以参考: https://docs.spring.io/spring-boot/docs/current/reference/html/deployment.html#deployment.cloud.kubernetes ## 7. 应用程序事件和侦听器 除了通常的 Spring Framework 事件(例如 ContextRefreshedEvent)之外,SpringApplication 还发送一些额外的应用程序事件。 注意:某些事件实际上是在创建 ApplicationContext 之前触发的,因此您不能将侦听器注册为 @Bean。 可以使用 SpringApplication.addListeners(… ) 方法或 SpringApplicationBuilder.listeners(… ) 方法注册它们。 应用程序运行时,应用程序事件按以下顺序发送: 1. ApplicationStartingEvent, 启动后, 开始处理之前, 排除监听器和初始化器的注册 2. ApplicationEnvironmentPreparedEvent , 环境应用在上下文, 上下文创建之前 3. ApplicationContextInitializedEvent , ApplicationContext 准备好,ApplicationContextInitializers 被呼叫, Bean 的定义加载之前 4. ApplicationPreparedEvent , Bean 定义加载之后, 刷新之前 5. ApplicationStartedEvent , 刷新上下文之后但在调用任何应用程序和命令行运行程序之前。 6. AvailabilityChangeEvent 在LivenessState.CORRECT 之后, 应用启动 7. ApplicationReadyEvent 任何应用程序和命令行运行程序被调用后执行。 8. AvailabilityChangeEvent ,ReadinessState.ACCEPTING_TRAFFIC 之后,准备好可以处理请求 9. ApplicationFailedEvent , 启动异常 上面的列表仅包括绑定到 SpringApplication 的 SpringApplicationEvents。 除此之外,以下事件也在 ApplicationPreparedEvent 之后和 ApplicationStartedEvent 之前发布 1. WebServerInitializedEvent WebServer 准备就绪。ServletWebServerInitializedEvent 和 ReactiveWebServerInitializedEvent 分别是 servlet 和reactive 2. ContextRefreshedEvent , ApplicationContext 刷新之后 提示: 通常不需要使用应用程序事件,但知道它们存在会很方便。 在内部,Spring Boot 使用事件来处理各种任务。 注意:默认情况下,事件侦听器不应运行在同一线程中执行的潜在冗长任务。 考虑改用应用程序和命令行运行程序。 应用程序事件是使用 Spring Framework 的事件发布机制发送的。 此机制的一部分确保发布到子上下文中的侦听器的事件也发布到任何祖先上下文中的侦听器。 因此,如果应用程序使用 SpringApplication 实例的层次结构,则侦听器可能会收到同一类型应用程序事件的多个实例。 为了让侦听器区分其上下文的事件和后代上下文的事件,它应该请求注入其应用程序上下文,然后将注入的上下文与事件的上下文进行比较。 上下文可以通过实现 ApplicationContextAware 或者,如果监听器是一个 bean,通过使用 @Autowired 注入。 ## 8. Web 环境 SpringApplication 尝试创建正确类型的 ApplicationContext。 如果是 Web应用,用于确定 WebApplicationType 的算法如下: 1. 如果存在 Spring MVC,则使用 AnnotationConfigServletWebServerApplicationContext 2. 如果 Spring MVC 不存在而 Spring WebFlux 存在,则使用 AnnotationConfigReactiveWebServerApplicationContext 3. 否则,使用 AnnotationConfigApplicationContext 如果同时存在Spring MVC 和Spring WebFlux, 则默认使用MVC, 可以使用 `setWebApplicationType(WebApplicationType). ` 进行设置。 也可以通过调用 setApplicationContextClass(… ) 来完全控制使用的 ApplicationContext 类型。 提示: 在 JUnit 测试中使用 SpringApplication 时,通常需要调用 setWebApplicationType(WebApplicationType.NONE)。 ## 9. 访问应用程序参数 如果需要获取传递给 SpringApplication.run(... ) 的应用程序参数,可以注入一个 org.springframework.boot.ApplicationArguments 类型的bean。 ApplicationArguments 接口提供对原始 String[] 参数以及解析的选项和非选项参数的访问,如下所示: ``` @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"] } } ``` 提示: Spring Boot 还向 Spring Environment 注册了一个 CommandLinePropertySource。 所以可以使用 @Value 注释注入单个应用程序参数。 ## 10. ApplicationRunner 和 CommandLineRunner 的使用 如果需要在 SpringApplication 启动后运行某些特定代码,可以实现 ApplicationRunner 或 CommandLineRunner 接口。 这两个接口的工作方式相同,并提供一个 run 方法,该方法在 SpringApplication.run(... ) 完成之前调用。 注意: 该方式非常适合应在应用程序启动之后但在开始接受流量之前运行的任务。 CommandLineRunner 接口提供对作为字符串数组的应用程序参数的访问,而 ApplicationRunner 使用 ApplicationArguments 接口。 以下示例显示了一个带有 run 方法的 CommandLineRunner: ``` @Component public class MyCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) { // Do something... } } ``` 如果定义了多个必须按特定顺序调用的 CommandLineRunner 或 ApplicationRunner bean,则可以另外实现 org.springframework.core.Ordered 接口或使用 org.springframework.core.annotation.Order 注释。 ## 11. 应用的退出 每个 SpringApplication 向 JVM 注册一个关闭钩子,以确保 ApplicationContext 在退出时正常关闭。 可以使用所有标准的 Spring 生命周期回调(例如 DisposableBean 接口或 @PreDestroy 注释)。 此外,如果 bean 希望在调用 SpringApplication.exit() 时返回特定的退出代码,它们可以实现 org.springframework.boot.ExitCodeGenerator 接口。 然后可以将此退出代码传递给 System.exit() 以将其作为状态代码返回,如以下示例所示: ``` public class MyApplication { @Bean public ExitCodeGenerator exitCodeGenerator() { return () -> 42; } public static void main(String[] args) { System.exit(SpringApplication.exit(SpringApplication.run(MyApplication.class, args))); } } ``` 此外,ExitCodeGenerator 接口可能由异常实现。 当遇到这样的异常时,Spring Boot 会返回实现的 getExitCode() 方法提供的退出代码。 ## 12. 管理功能 通过指定` spring.application.admin.enabled `属性为应用程序启用与管理相关的功能。这将在平台 MBeanServer 上公开 SpringApplicationAdminMXBean。 可以使用此功能远程管理您的 Spring Boot 应用程序。 此功能也可用于任何服务包装器实现。 提示: 如果想知道应用程序在哪个 HTTP 端口上运行,使用 local.server.port 键获取属性。 ## 13. 应用程序启动跟踪 在应用程序启动过程中,SpringApplication 和 ApplicationContext 执行许多与应用程序生命周期、bean 生命周期甚至处理应用程序事件相关的任务。 通过 ApplicationStartup,Spring Framework 允许您使用 StartupStep 对象跟踪应用程序启动顺序。 可以收集这些数据用于分析目的,或者只是为了更好地了解应用程序启动过程。 可以在设置 SpringApplication 实例时选择 ApplicationStartup 实现。 例如,要使用 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); } } ``` 第一个可用的实现 FlightRecorderApplicationStartup 由 Spring Framework 提供。 它将特定于 Spring 的启动事件添加到 Java Flight Recorder 会话中,用于分析应用程序并将其 Spring 上下文生命周期与 JVM 事件(例如分配、GC、类加载......)相关联。 配置完成后,可以通过在启用Flight记录器的情况下运行应用程序来记录数据: ``` $ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar ``` Spring Boot 附带了 BufferingApplicationStartup 变体; 此实现旨在缓冲启动步骤并将它们排入外部指标系统。 应用程序可以在任何组件中请求类型为 BufferingApplicationStartup 的 bean。 Spring Boot 还可以配置为公开一个启动端点,该端点以 JSON 文档的形式提供此信息。 ***** ***** 如果您希望自动注册这些侦听器,无论应用程序的创建方式如何,您都可以将 META-INF/spring.factories 文件添加到您的项目中,并使用 org.springframework.context 引用您的侦听器。 ApplicationListener 键,如下例所示: 也可以添加 META-INF/spring.factories 文件。 使用如下方式注册: ``` org.springframework.context.ApplicationListener=com.example.project.MyListener ``` 应用的事件是有顺序的: * 在实际开发中, 应用的事件一般较少使用 * | | | | --- | --- | | addInitializers()| | | addListeners | | | addPrimarySources | | | setAddCommandLineProperties | | | setAddConversionService | | | setAdditionalProfiles | | | setAllowBeanDefinitionOverriding | | | setBanner | | | setBannerMode | | | setDefaultProperties | | | setEnvironment | | | setHeadless | | | setLazyInitialization | | | setLogStartupInfo | | | setWebApplicationType | | | ... | | 具体参考: https://docs.spring.io/spring-boot/docs/2.5.5/api/org/springframework/boot/SpringApplication.html * 使用 Kubernetes Probes , 使用actuator * 继承 ApplicationAvailability 接口 1. 活动状态(Liveness State), 内部状况,不依赖外部检查 2. 准备状态(Readiness State),运行之后进入该状态 3. 管理应用的可用状态 可以将应用的准备状态到处到文件, Kubernetes 的 “exec Probe” 就可以使用这个文件。 应用中断无法恢复时,可以更新应用的状态: Spring Boot提供了 Kubernetes 的HTTPS 探测器来探测 Liveness和Readiness 状态。可以参考: https://docs.spring.io/spring-boot/docs/current/reference/html/deployment.html#deployment.cloud.kubernetes