在上一篇文章中,我们介绍了 Spring Boot
提供的 DevTools
,在本篇文章中,将介绍 SpringApplication
这个类。
在之前的文章中,我们知道了 SpringApplication
是 Spring Boot
应用的入口,在本文中,将深入介绍 SpringApplication
的一些其它特性。
SpringApplication
提供了一个静态方法(run
),使得我们可以通过 main
方法来启动 Spring
应用程序。如下所示:
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}
当应用启动成功后,你应该看到以下的内容:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v2.1.0.RELEASE
2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166 INFO 56603 --- [ main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.ser[emailprotected]6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912 INFO 41370 --- [ main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501 INFO 41370 --- [ main] o.s.b.s.app.SampleApplication : Started SampleApplication in 2.992 seconds (JVM running for 3.658)
在默认情况下,它会打印 INFO
级别的日志,并输出一些启动相关的消息,如:应用端口、程序 PID
,启动程序的用户等。如果你希望看到更详细的信息,可以通过外部配置的方式,指定以 debug
模式启动应用,或是直接通过修改系统日志的配置,来显示更为详细的信息。
当你的应用启动失败时,你通常会得到类似下面的错误提示:
***************************
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.
以上的提示就是通过 Spring Boot
提供的 FailureAnalyzers
来展示给我们的,它能让我们更加清楚的知道应用为什么会无法启动,如上面给的提示,非常明确的告诉我们 8080
的端口已经被占用,导致了程序无法启动。
SPring Boot
已经内置了常见的一些 FailureAnalyzers
,如果这些无法满足你项目的需求,你也可以自己实现它。
当然,如果没有任何 FailureAnalyzers
能够处理启动异常,你也可以通过其他途径来获取详细的异常堆栈信息:
debug
模式启动应用debug
级别例如,如果你使用的是 java -jar
的方式启动的应用,则可以按照以下方式启用 debug
模式:
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
这是个非常好玩的功能,Banner
指的就是当系统启动时,最开始打印的内容,如:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v1.5.9.RELEASE
以上的内容,我们可以自行定义。我们只需要在项目 classpath
下添加 banner.txt
,并在里面输入 banner
的内容即可,默认情况下,banner.txt
将会使用 UTF-8
编码解析,如果你需要制定编码,可以设置 banner.charset
属性。下表列出了在 banner.txt
中支持的变量:
Variable | Description |
---|---|
${application.version} |
The version number of your application as declared in MANIFEST.MF . For exampleImplementation-Version: 1.0 is printed as 1.0 . |
${application.formatted-version} |
The version number of your application as declared in MANIFEST.MF formatted for display (surrounded with brackets and prefixed with v ). For example (v1.0) . |
${spring-boot.version} |
The Spring Boot version that you are using. For example 1.5.19.RELEASE . |
${spring-boot.formatted-version} |
The Spring Boot version that you are using formatted for display (surrounded with brackets and prefixed with v ). For example (v1.5.19.RELEASE) . |
${Ansi.NAME} (or ${AnsiColor.NAME} , ${AnsiBackground.NAME} , ${AnsiStyle.NAME} ) |
Where NAME is the name of an ANSI escape code. See AnsiPropertySource for details. |
${application.title} |
The title of your application as declared in MANIFEST.MF . For exampleImplementation-Title: MyApp is printed as MyApp . |
最强大的是,banner
不仅支持文字,它还可以支持 .git
和 .jpg
格式的图像,只需要设置 banner.image.location
属性即可,有兴趣的可以自己去实验。
如果你想禁用 banner
,也非常简单,可以通过以下方式:
spring:
main:
banner-mode: "off"
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
如果默认设置不满足你的需求,你也可以自行定义它。自定义 SpringApplication
有两种方式,第一就是传统的方式,设置类的属性值,如上面设置 banner mode
;还有一种方式是使用 Builder
模式进行设置,如:
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
SpringApplication
在启动、运行和关闭的时候,将会注册一系列的事件供我们去订阅。
这里有一点需要注意的是,因为某些事件是在
ApplicationContext
创建之前就被触发的,所以不能将它们注册为 @Bean,只能通过SpringApplication.addListeners(…)
或SpringApplicationBuilder.listeners(…)
的方式去注册它,如果你希望它们被自动注册,你也可以在应用classpath
下面添加META-INF/spring.factories
文件,并在启动添加以下内容:
org.springframework.context.ApplicationListener=com.example.project.MyListener
以下是当你应用运行时,一些事件的发生顺序:
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationPreparedEvent
ApplicationReadyEvent
ApplicationFailedEvent
Spring Boot
应用会尝试去创建正确的应用程序上下文。默认情况下,AnnotationConfigApplicationContext
或是 AnnotationConfigEmbeddedWebApplicationContext
将被创建,具体创建哪一个上下文基于你开发的是否是一个 Web
程序。当然,你也可以通过编程方式去指定它:setWebEnvironment(boolean webEnvironment)
。
当你需要从命令行或是其它方式指定应用的参数时,你可以通过以下方式去获取这些参数:
**通过 ApplicationArguments **
ApplicationArguments
接口提供了一些方法让我们非常方便的访问应用的参数:
public interface ApplicationArguments {
String[] getSourceArgs();
Set<String> getOptionNames();
boolean containsOption(String name);
List<String> getOptionValues(String name);
List<String> getNonOptionArgs();
}
如:
import org.springframework.boot.*
import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
}
}
通过 @Value 注解
Spring Boot
将会把应用参数注册为 CommandLinePropertySource
,这就使得我们可以通过 @Value
注解方式去访问这些参数。
如果你需要在程序启动时运行某些特殊的代码,你可以实现 ApplicationRunner
或是 CommandLineRunner
,它们都提供了 run
方法,此方法将在 SpringApplication.run(…)
执行完成之前被调用。两者除了入参不同外其他的都相同。CommandLineRunner
将使用字符串数组作为参数,而 ApplicationRunner
则使用 ApplicationArguments
作为参数。如:
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
每一个 SpringApplication
都将注册一个关闭钩子,用于确保应用被优雅的关闭。
略
本文介绍了 SpringApplication
这个类的一些特性,在下一篇文章中,将介绍 Spring Boot
应用的外部配置。