目录
Startup Failure启动失败
Lazy Initialization懒加载
Customizing the Banner自定义横幅
Application Availability
Application Events and Listeners应用事件和监听器
Web Environment
Accessing Application Arguments(访问应用程序参数)
Using the ApplicationRunner or CommandLineRunner
Application Exit
Admin Features
Application Startup tracking
SpringApplication类提供了一个方便的方式启动,由main()方法启动。很多情形你可以委托给static 的 SpringApplication.run 比如下面这样:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
当你的项目启动你将在控制台上看到如下日志
. ____ _ __ _ _ /\ / ___'_ __ _ _(_)_ __ __ _ ( ( )___ | '_ | '_| | '_ / _` | \/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |___, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: v2.5.5 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,包括一些相关的启动详情,比如启动程序的用户。如果你想改变日志级别,请在Log Levels更改。如果你想关掉,配置这个属性spring.main.log-startup-info 为false。
另外你也可以重写SpringApplication 子类的logStartupInfo(boolean)方法。
Startup Failure启动失败
如果你的程序启动失败,被注册的
FailureAnalyzers
获得一次提供专用的错误信息,和具体修复的动作的机会。下面这个例子,错误描述:表明8080端口已经被占用,恢复动作:定义和停止监听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.
Lazy Initialization懒加载
sprigApplication允许程序懒加载。如下配置即可实现
Propertiesspring.main.lazy-initialization=trueYaml
spring: main: lazy-initialization: true
Customizing the Banner自定义横幅
把想要的横幅
banner.txt
文件放入classpath上即可生效。
Customizing SpringApplication自定义springApplication
方式1
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
方式2Fluent Builder API
new SpringApplicationBuilder() .sources(Parent.class) .child(Application.class) .bannerMode(Banner.Mode.OFF) .run(args);
Application Availability
略
Application Events and Listeners应用事件和监听器
spring framework 事件,比如ContextRefreshedEvent一个springApplication会发送一些应用事件。
一些事件事件上在ApplicationContext被创建之前是被触发的,所以你不能注册一个监听器当做一个@Bean.你可以注册它们使用SpringApplication.addListeners(…) method 或者
SpringApplicationBuilder.listeners(…) method . 如果你想这写监听器自动被注册,忽略应用的启动方式,你可以把你相关的监听器放入 meta-INF/spring.factories 使用 org.springframework.context.ApplicationListener这个,比如:org.springframework.context.ApplicationListener=com.example.project.MyListener
当你的应用运行时,应用事件被发送的顺序:
- ApplicationStartingEvent
- ApplicationEnvironmentPreparedEvent
- ApplicationContextInitializedEvent
- ApplicationPreparedEvent
- ApplicationStartedEvent
- AvailabilityChangeEvent
- ApplicationReadyEvent
- AvailabilityChangeEvent
- ApplicationFailedEvent
上述这个事件列表仅仅是被绑定到springApplication的事件。下面这些事件的顺序是4ApplicationPreparedEvent之后,5 ApplicationStartedEvent之前:
WebServerInitializedEvent 是在 WebServer 准备好之后发送。 ServletWebServerInitializedEvent 是servlet. ReactiveWebServerInitializedEvent 是r eactive。当一个 ApplicationContext 被刷新 ContextRefreshedEvent 被发送。 你一般不用这些应用事件,但是它们的存在能被方便的操作。springboot内部使用这些事件完成各式各样的任务。 当事件监听器默认执行在同样的线程,它们应该不允许一些潜在的冗余任务。考虑用 application and command-line runners 代替 应用事件是被spring框架的事件发送机制发送的。发送机制的一部分确保一个事件发布给一个在子上下文( child context)的监听器( listeners),也能发布在任何祖先上下文( ancestor contexts)的监听器( listeners)。综上,如果你的应用使用层次的 SpringApplication 的实例,一个监听器(listener)可能收到多个实例的同一类型的事件。 允许你的监听器区分当前上下文( context)事件和后代上下文( descendant context)事件,应该要求一个应用上下文是被注入的,然后比较注入的上下文和事件的上下文。这个上下文能被实现了 ApplicationContextAware的 注入,或者如果这个监听器是一个 Bean ,使用 @AutowiredWeb Environment
一个SpringApplication企图代表你创建一个合适的正确的ApplicationContext。WebApplicationType取决于下面的算法:
如果是SpringMVC,使用AnnotationConfigServletWebServerApplicationContext。
如果是Spring WebFlux,使用AnnotationConfigReactiveWebServerApplicationContext。
其他,使用AnnotationConfigApplicationContext。
这个意味着你,如果使用Spring MVC和从Spring WebFlux新的WebClient在同一个应用。
Spring MVC将被默认使用。你能简单地重写 setWebApplicationType(WebApplicationType)。 使用 setApplicationContextClass(…) ,可以完全获得 ApplicationContext 类型的控制权。 tip :当使用 JUnit test内部时,它经常调用 setWebApplicationType(WebApplicationType.NONE)。Accessing Application Arguments(访问应用程序参数)
如果你想访问被传递的应用程序参数,你能注入org.springframework.boot.ApplicationArguments bean,ApplicationArguments接口提供访问的原始String[]还有被解析的option和non-option参数,如下例子:
@Component
public class MyBean {
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List files = args.getNonOptionArgs();
if (debug) {
System.out.println(files);
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
tip:Spring Boot使用Spring Environment注册了一个CommandLinePropertySource。
这让你使用@Value annotation注入一个单独应用参数。
Using the ApplicationRunner or CommandLineRunner
一旦一个SpringApplication已经被启动了,你需要运行一些特定的代码,你能通过实现
ApplicationRunner 或者 CommandLineRunner 接口完成。两个接口以同样的工作方式,提供一个单独的run方法,它们时在 SpringApplication.run(…) 完成之前调用。 这个协议非常适用一些任务,应该运行应用启动之后但是开始流量之前。 CommandLineRunner 参数是String[], ApplicationRunner 参数是 ApplicationArguments@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// Do something...
}
}
如果有多个CommandLineRunner or ApplicationRunner beans被定义,必须遵守执行的顺序,有两种实现方式,1实现这个org.springframework.core.Ordered接口
2使用org.springframework.core.annotation.Order注解
Application Exit
每个SpringApplication注册一个关闭的钩子通过JVM,确保Jvm退出时ApplicationContext被优雅的关闭。所以标准的Spring生命周期回调DisposableBean接口或者使用@PreDestroy注解。
此外Bean实现org.springframework.boot.ExitCodeGenerator接口,如果它们期望当程序退出时会得到一个具体的退出码。这个码作为一个状态码返回被传递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)));
}
}



