1. SpringApplication
SpringApplication类提供了一种方便的方式来引导一个从main()方法启动的Spring应用程序。在很多情况下,你可以委托给静态的SpringApplication.run方法,如下例所示:
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); } }
当你的应用程序启动时,你应该会看到类似如下的输出:
@SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } When your application starts, you should see something similar to the following output: . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: v2.6.4 2021-02-03 10:33:25.224 INFO 17321 --- [ main] o.s.b.d.s.s.SpringApplicationExample : Starting SpringApplicationExample 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.SpringApplicationExample : 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.SpringApplicationExample : Started SampleTomcatApplication in 1.514 seconds (JVM running for 1.823)
默认情况下,会显示INFO日志消息,包括一些相关的启动细节,比如启动应用程序的用户。如果您需要设置除INFO之外的日志级别,请参见日志级别(Log Levels)进行设置。应用程序版本是使用来自主应用程序类包的实现版本来确定的。可以通过将spring.main.log-startup-info设置为false来关闭启动信息日志记录(Startup information logging)。这也将关闭应用程序的活动概要文件(the application’s active profiles)的日志记录。
要在启动时添加额外的日志记录,你可以在SpringApplication的子类中重写logStartupInfo(boolean)
1.1. Startup Failure
显示完整的条件报告,以更好地理解出错的原因。
例如,如果你使用java -jar运行你的应用程序,你可以启用debug属性,如下所示:
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
1.3. Customizing the Banner
可以通过在类路径中添加一个banner.txt文件或将spring.banner.location属性设置为该文件的位置来更改启动时打印的横幅。如果文件的编码不是UTF-8,可以设置spring.banner.charset。除了文本文件外,还可以向类路径(PS. 放在application.properties同一目录,也就是resources目录下,简单的黑白图片效果很不错,关于资源放在哪可以参考“Maven入门_如何向JAR添加资源&标准目录布局”,当然,springboot项目打包后的目录结构会不一样,详见The Executable Jar Format)中添加banner.gif、banner.jpg或banner.png图像文件,或者设置spring.banner.image.location属性。图像被转换成ASCII艺术表示,并打印在任何文本横幅上方。
在你的banner.txt文件中,你可以使用Environment中可用的任何key以及以下任何占位符(参见Table 1. Banner variables)
如果您希望以编程方式生成横幅,可以使用SpringApplication.setBanner(…)方法。使用org.springframework.boot.Banner接口并实现您自己的printBanner()方法。
你也可以使用spring.main.banner-mode属性来确定是否必须在System.out (console)打印横幅,发送到配置的记录器(log),或根本不产生(off)。
打印出来的横幅被注册为一个单例bean,名字如下:springBootBanner。
1.4. Customizing SpringApplication
如果SpringApplication的默认值不合你的口味,你可以创建一个本地实例并对其进行定制。例如,要关闭横幅,你可以这样写:
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); } }
(传递给SpringApplication的构造函数参数是Spring bean的配置源。在大多数情况下,这些是对@Configuration类的引用,但它们也可以是对@Component类的直接引用)
也可以通过使用一个application.properties文件来配置SpringApplication。有关详细信息,请参阅外部化配置( Externalized Configuration)。
有关配置选项的完整列表(a complete list of the configuration options),请参阅SpringApplication Javadoc
1.7. Application Events and Listeners
除了通常的Spring框架事件,比如ContextRefreshedEvent, SpringApplication还会发送一些额外的应用事件。
(有些事件实际上是在ApplicationContext创建之前被触发的,所以你不能在这些事件上注册一个listener作为@Bean。你可以用SpringApplication.addListeners(…)方法或SpringApplicationBuilder.listeners(…)方法注册它们。
如果您希望自动注册这些侦听器,而不管应用程序是以何种方式创建的,那么您可以添加一个META-INF/spring.factories到你的项目,并通过使用org.springframework.context.ApplicationListener键引用你的listener(s),如下所示:
org.springframework.context.ApplicationListener=com.example.project.MyListener
)
当你的应用程序运行时,应用程序事件按以下顺序发送:
- x
- x
- x
- x
- x
上面的列表只包括绑定到SpringApplication的SpringApplicationEvents。除此之外,以下事件也会在ApplicationPreparedEvent之后和ApplicationStartedEvent之前发布:
- 一个WebServerInitializedEvent在WebServer准备好之后被发送。ServletWebServerInitializedEvent和ReactiveWebServerInitializedEvent分别是servlet和响应式变量。
- 当ApplicationContext刷新时,ContextRefreshedEvent被发送。
(您通常不需要使用应用程序事件,但知道它们的存在会很方便。在内部,Spring Boot使用事件来处理各种任务)
(默认情况下,Event listeners在同一线程中执行时,不应运行可能冗长的任务。考虑使用应用程序和命令行运行器。)
应用程序事件(Application events)是通过使用Spring Framework的事件发布机制发送的。该机制的一部分确保在子上下文中(in a child context)发布到侦听器的事件也会发布到任何祖先上下文中(any ancestor contexts)的侦听器。因此,如果应用程序使用SpringApplication实例的层次结构,一个侦听器(a listener)可能会接收到相同类型的应用程序事件的多个实例。
要让侦听器区分上下文的事件和后代上下文的事件,它应该请求注入其应用程序上下文,然后将注入的上下文与事件的上下文进行比较。context可以通过实现ApplicationContextAware注入,如果侦听器是一个bean,也可以通过使用@Autowired注入。
1.8. Web Environment
SpringApplication试图为您创建正确类型的ApplicationContext。用来确定WebApplicationType的算法如下:
- If Spring MVC is present, an AnnotationConfigServletWebServerApplicationContext is used
- If Spring MVC is not present and Spring WebFlux is present, an AnnotationConfigReactiveWebServerApplicationContext is used
- Otherwise, AnnotationConfigApplicationContext is used
这意味着,如果你在同一个应用程序中使用Spring MVC和来自Spring WebFlux的新WebClient,那么默认情况下会使用Spring MVC。你可以通过调用setWebApplicationType(WebApplicationType)轻松覆盖它。
也可以通过调用setApplicationContextClass(…)来完全控制ApplicationContext类型。
(当在JUnit测试中使用SpringApplication时,通常需要调用setWebApplicationType(WebApplicationType.NONE)
1.13. Application Startup tracking
在应用程序启动期间,SpringApplication和ApplicationContext执行许多与应用程序生命周期、bean生命周期甚至处理应用程序事件相关的任务。使用ApplicationStartup, Spring框架允许你使用StartupStep对象跟踪应用程序的启动顺序。收集这些数据可以用于分析目的,或者只是为了更好地理解应用程序的启动过程。
在设置SpringApplication实例时,您可以选择一个ApplicationStartup实现。例如,要使用BufferingApplicationStartup,你可以这样写:
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); } }
第一个可用的实现FlightRecorderApplicationStartup是由Spring Framework提供的。它将Spring特定的启动事件添加到Java Flight Recorder会话中,用于分析应用程序,并将它们的Spring上下文生命周期与JVM事件(如分配、gc、类加载……)关联起来。配置完成后,你可以通过启用Flight Recorder运行应用程序来记录数据:
$ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
Spring Boot自带BufferingApplicationStartup变量;这个实现是为了buffering启动步骤,并将它们放入外部度量系统中(an external metrics system)。应用程序可以在任何组件中请求BufferingApplicationStartup类型的bean。
Spring Boot还可以配置成暴露一个启动端点(startup
endpoint ),该端点以JSON文档的形式提供该信息。