赞
踩
本文将深入介绍springBoot框架得特性,此处可助您了解springBoot自身特性,为后续工程架构铺平道路
1、springBoot应用
springApplication类提供了一个方便得方式来引导启动spring应用得main方法。在许多情况下您可以委托给静态SpringApplication.run
方法,如下例所示:
- @SpringBootApplication
- public class MyApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(MyApplication.class, args);
- }
-
- }
应用程序启动后 ,您将会从控制台上看到如下:
- . ____ _ __ _ _
- /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
- ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
- \\/ ___)| |_)| | | | | || (_| | ) ) ) )
- ' |____| .__|_| |_|_| |_\__, | / / / /
- =========|_|==============|___/=/_/_/_/
- :: Spring Boot :: v2.5.6
-
- 2021-02-03 10:33:25.224 INFO 17321 --- [ main] o.s.b.d.s.s.SpringAppplicationExample : Starting SpringAppplicationExample using Java 1.8.0_232 on mycomputer with PID 17321 (/apps/myjar.jar started by pwebb)
- 2021-02-03 10:33:25.226 INFO 17900 --- [ main] o.s.b.d.s.s.SpringAppplicationExample : No active profile set, falling back to default profiles: default
- 2021-02-03 10:33:26.046 INFO 17321 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
- 2021-02-03 10:33:26.054 INFO 17900 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
- 2021-02-03 10:33:26.055 INFO 17900 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
- 2021-02-03 10:33:26.097 INFO 17900 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
- 2021-02-03 10:33:26.097 INFO 17900 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 821 ms
- 2021-02-03 10:33:26.144 INFO 17900 --- [ main] s.tomcat.SampleTomcatApplication : ServletContext initialized
- 2021-02-03 10:33:26.376 INFO 17900 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
- 2021-02-03 10:33:26.384 INFO 17900 --- [ main] o.s.b.d.s.s.SpringAppplicationExample : Started SampleTomcatApplication in 1.514 seconds (JVM running for 1.823)
默认情况下,日志消息显示info级别,包括一些相关的启动详细信息,例如启动应用程序的用户。如果您需要除 之外的日志级别INFO
,您可以设置它,如日志级别中所述。应用程序版本是使用主应用程序类包中的实现版本确定的。可以通过设置spring.main.log-startup-info
为关闭启动信息记录false
。这也将关闭应用程序的活动配置文件的日志记录。
1.1启动失败
如果您的应用程序无法启动,注册FailureAnalyzers
有机会提供专门的错误消息和解决问题的具体操作。例如,如果您在端口上启动 Web 应用程序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's listening on port 8080 or configure this application to listen on another port.
如果没有全局异常处理,您任然可以显示完整得条件报告以更好地了解除了什么问题。要做到这一点,你需要开启debug级别日志或者以debug级别启动程序
例如,如果您使用java -jar 运行您得程序,以debug级别启动,您可以如下方式操作
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
1.2.延迟初始化
SpringApplication
允许延迟初始化应用程序。启用延迟初始化后,bean 将在需要时创建,而不是在应用程序启动期间创建。因此,启用延迟初始化可以减少应用程序启动所需的时间。在 Web 应用程序中,启用延迟初始化将导致许多与 Web 相关的 bean 在收到 HTTP 请求之前不会被初始化。
延迟初始化的一个缺点是它会延迟发现应用程序的问题。如果一个错误配置的 bean 被延迟初始化,那么在启动过程中将不再发生故障,并且只有在 bean 初始化时问题才会变得明显。还必须注意确保 JVM 有足够的内存来容纳所有应用程序的 bean,而不仅仅是那些在启动期间初始化的 bean。由于这些原因,默认情况下不启用延迟初始化,建议在启用延迟初始化之前对 JVM 的堆大小进行微调。
可以使用lazyInitialization
on 方法SpringApplicationBuilder
或setLazyInitialization
on方法以编程方式启用延迟初始化SpringApplication
。或者,可以使用spring.main.lazy-initialization
以下示例中所示的属性启用它(即在配置文件中配置以下属性):
spring.main.lazy-initialization=true
1.3.自定义控制台打印横幅
可以通过将banner.txt
文件添加到类路径或将spring.banner.location
属性设置为此类文件的位置来更改启动时打印的横幅。如果文件的编码不是 UTF-8,您可以设置spring.banner.charset
. 除了一个文本文件,你还可以添加一个banner.gif
,banner.jpg
或banner.png
图像文件到类路径或设置spring.banner.image.location
属性。图像被转换为 ASCII 艺术表现形式并打印在任何文本横幅上方。
横幅得变量如下
变量 | 描述 |
---|---|
| 应用程序的版本号,如 |
| 应用程序的版本号,如在 中声明 |
| 您正在使用的 Spring Boot 版本。例如 |
| 您正在使用的 Spring Boot 版本,已格式化以显示(用括号括起来并以 为前缀 |
|
|
| 您的应用程序的标题,如 |
如下图示例:
您还可以使用该spring.main.banner-mode
属性来确定横幅是否必须打印在System.out
( console
)、发送到配置的记录器 ( log
) 或根本不生成 ( off
)。
打印的横幅在以下名称下注册为单例 bean:springBootBanner
.
1.4.自定义SpringApplication
如果SpringApplication
默认设置不合您的口味,您可以改为创建本地实例并对其进行自定义。例如,要关闭横幅,您可以编写:
- package com.example.demo;
-
- import org.springframework.boot.Banner;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- @SpringBootApplication
- public class DemoApplication {
-
- public static void main(String[] args) {
- SpringApplication application = new SpringApplication(DemoApplication.class);
- application.setBannerMode(Banner.Mode.OFF);
- application.run(args);
- }
-
- }
1.5.流利得构建器API
如果您需要构建ApplicationContext
层次结构(具有父/子关系的多个上下文),或者如果您更喜欢使用“流畅”构建器 API,则可以使用SpringApplicationBuilder
.
在SpringApplicationBuilder
让要链接的多个方法调用,并且包括parent
和child
其让你创建层次结构,以显示在下面的示例性方法:
- new SpringApplicationBuilder()
- .sources(Parent.class)
- .child(Application.class)
- .bannerMode(Banner.Mode.OFF)
- .run(args);
1.6.应用程序可用性
在平台上部署时,应用程序可以使用Kubernetes Probes等基础设施向平台提供有关其可用性的信息。Spring Boot 包括对常用“活跃”和“就绪”可用性状态的开箱即用支持。如果您使用 Spring Boot 的“执行器”支持,那么这些状态将作为健康端点组公开。
此外,您还可以通过将ApplicationAvailability
接口注入您自己的 bean来获取可用性状态。
1.6.1活跃状态
应用程序的“活跃度”状态表明它的内部状态是否允许它正常工作,或者如果它当前失败则自行恢复。损坏的“Liveness”状态意味着应用程序处于无法恢复的状态,基础设施应该重新启动应用程序
一般来说,“Liveness”状态不应基于外部检查,例如Health 检查。如果确实如此,则出现故障的外部系统(数据库、Web API、外部缓存)将触发整个平台的大规模重启和级联故障。
Spring Boot 应用程序的内部状态主要由 Spring 表示ApplicationContext
。如果应用程序上下文已成功启动,Spring Boot 会假定应用程序处于有效状态。一旦上下文刷新,应用程序就被认为是活动的,请参阅Spring Boot 应用程序生命周期和相关的应用程序事件。
1.6.2.准备状态
应用程序得就绪状态表明应用程序是否已准备好处理流量。失败的“就绪”状态告诉平台它现在不应将流量路由到应用程序。这通常在启动过程中发生的,而CommandLineRunner
和ApplicationRunner
组件正在处理,或在任何时候,如果应用程序决定实在是太忙了额外的流量。
1.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;
- }
- }
- }
我们还可以在应用程序中断且无法恢复时更新应用程序的状态:1.
@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); } } }
1.7.应用程序事件和侦听器
除了通常的 Spring Framework 事件(例如 )之外ContextRefreshedEvent,a SpringApplication
还会发送一些额外的应用程序事件。
某些事件实际上ApplicationContext
是在创建之前触发的,因此您不能将这些事件注册为@Bean
. 您可以使用SpringApplication.addListeners(…)
方法或SpringApplicationBuilder.listeners(…)
方法注册它们。
如果您希望自动注册这些侦听器,无论应用程序的创建方式如何,您都可以将META-INF/spring.factories
文件添加到您的项目并使用org.springframework.context.ApplicationListener
密钥引用您的侦听器,如以下示例所示:
org.springframework.context.ApplicationListener=com.example.project.MyListener
当您的应用程序运行时,应用程序事件按以下顺序发送:
AnApplicationStartingEvent
在运行开始时发送,但在任何处理之前发送,除了侦听器和初始化程序的注册。
一个ApplicationEnvironmentPreparedEvent
当被发送Environment
到中已知的上下文中使用,但是在创建上下文之前。
一个ApplicationContextInitializedEvent
在当发送ApplicationContext
准备和ApplicationContextInitializers一直呼吁,但被加载任何bean定义之前。
ApplicationPreparedEvent
在刷新开始之前但在加载 bean 定义之后发送一个。
AnApplicationStartedEvent
在上下文刷新后但在调用任何应用程序和命令行运行程序之前发送。
紧随AvailabilityChangeEvent
其后发送 ,LivenessState.CORRECT
以指示应用程序被视为实时应用程序。
在调用ApplicationReadyEvent
任何应用程序和命令行运行程序后发送一个。
AvailabilityChangeEvent
在 with 之后立即发送一个,ReadinessState.ACCEPTING_TRAFFIC
以指示应用程序已准备好为请求提供服务。
一个ApplicationFailedEvent
如果在启动时异常发送。
上面的列表只包括SpringApplicationEvent
绑定到 a 的 s SpringApplication
。除此之外,以下事件也在 之后ApplicationPreparedEvent
和之前发布ApplicationStartedEvent
:
准备好 WebServerInitializedEvent
后发送A。和分别是 servlet 和反应式变体。WebServer
ServletWebServerInitializedEvent
ReactiveWebServerInitializedEvent
刷新ContextRefreshedEvent
时发送A。ApplicationContext
应用程序事件通过使用 Spring Framework 的事件发布机制发送。此机制的一部分确保发布到子上下文中的侦听器的事件也发布到任何祖先上下文中的侦听器。因此,如果您的应用程序使用SpringApplication
实例层次结构,则侦听器可能会收到同一类型应用程序事件的多个实例。
为了让您的侦听器区分其上下文的事件和后代上下文的事件,它应该请求注入其应用程序上下文,然后将注入的上下文与事件的上下文进行比较。上下文可以通过实现注入,ApplicationContextAware
或者如果侦听器是 bean,则使用@Autowired
.
1.8.网络环境
a SpringApplication
尝试ApplicationContext
代表您创建正确的类型。用于确定 a 的算法WebApplicationType
如下:
如果存在 Spring MVC,AnnotationConfigServletWebServerApplicationContext
则使用an
如果 Spring MVC 不存在而 Spring WebFlux 存在,AnnotationConfigReactiveWebServerApplicationContext
则使用
否则,AnnotationConfigApplicationContext
使用
这意味着如果您WebClient
在同一个应用程序中使用 Spring MVC 和来自 Spring WebFlux的 new ,则默认情况下将使用 Spring MVC。您可以通过调用轻松覆盖它setWebApplicationType(WebApplicationType)
。
还可以ApplicationContext
通过调用完全控制使用的类型setApplicationContextClass(…)
。
如果您需要访问传递给 的应用程序参数SpringApplication.run(…)
,您可以注入一个org.springframework.boot.ApplicationArguments
bean。所述ApplicationArguments
接口提供访问两个原始String[]
以及解析参数option
和non-option
参数,如下面的例子所示:
- @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"]
- }
- }
1.10. 使用 ApplicationRunner 或 CommandLineRunner
如果您需要在启动后运行某些特定代码SpringApplication
,您可以实现ApplicationRunner
或CommandLineRunner
接口。这两个接口的工作方式相同,并提供一个run
方法,在SpringApplication.run(…)
完成之前调用该方法。
该合约非常适合应在应用程序启动之后但在开始接受流量之前运行的任务。 |
所述CommandLineRunner
接口提供访问的应用程序的参数作为一个字符串数组,而ApplicationRunner
用途ApplicationArguments
接口前面讨论。以下示例显示了CommandLineRunner
一个run
方法:
- @Component
- public class MyCommandLineRunner implements CommandLineRunner {
-
- @Override
- public void run(String... args) {
- // Do something...
- }
- }
如果几个CommandLineRunner
或ApplicationRunner
豆类中定义必须在一个特定的顺序被调用,您还可以实现org.springframework.core.Ordered
接口或使用org.springframework.core.annotation.Order
注解。
每个都SpringApplication
向 JVM 注册一个关闭钩子,以确保ApplicationContext
退出时正常关闭。可以使用所有标准的 Spring 生命周期回调(例如DisposableBean
接口或@PreDestroy
注解)。
此外,org.springframework.boot.ExitCodeGenerator
如果bean希望在SpringApplication.exit()
调用时返回特定的退出代码,它们可以实现该接口。然后可以将此退出代码传递给以将System.exit()
其作为状态代码返回,如以下示例所示:
- @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)));
- }
-
- }
此外,ExitCodeGenerator
接口可以通过异常来实现。当遇到这样的异常时,Spring Boot 会返回实现getExitCode()
方法提供的退出码。
可以通过指定spring.application.admin.enabled
属性为应用程序启用与管理相关的功能。这SpringApplicationAdminMXBean在平台上暴露了MBeanServer
。您可以使用此功能远程管理您的 Spring Boot 应用程序。此功能也可用于任何服务包装器实现。
在应用程序启动期间,SpringApplication
和ApplicationContext
执行许多与应用程序生命周期、bean 生命周期甚至处理应用程序事件相关的任务。有了ApplicationStartup,Spring Framework允许您使用StartupStep对象跟踪应用程序启动顺序。收集这些数据是为了分析目的,或者只是为了更好地了解应用程序启动过程。
您可以ApplicationStartup
在设置SpringApplication
实例时选择一个实现。例如,要使用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、类加载......)相关联。配置完成后,您可以通过在启用飞行记录器的情况下运行应用程序来记录数据:
$ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
Spring Boot 随附BufferingApplicationStartup
变体;此实现旨在缓冲启动步骤并将它们排入外部指标系统。应用程序可以BufferingApplicationStartup
在任何组件中请求类型的 bean 。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。