# 23\. SpringApplication
SpringApplication类提供了一种方便的方法来引导将从main()方法启动的Spring应用程序。 在许多情况下,您只需委派静态SpringApplication.run()方法:
```
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}
```
当您的应用程序启动时,您应该看到类似于以下内容:
```
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v1.5.2.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] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@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.TomcatEmbeddedServletContainerFactory : 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 级别log消息,包括用户启动应用程序一些相关的启动细节。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#231-启动失败)23.1 启动失败
如果您的应用程序无法启动,则注册的FailureAnalyzers会提供专门的错误消息和具体操作来解决问题。 例如,如果您在端口8080上启动Web应用程序,并且该端口已在使用中,则应该会看到类似于以下内容的内容:
```
***************************
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提供了众多的FailureAnalyzer实现,您可以非常容易地[添加自己的实现](http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#howto-failure-analyzer)。
如果没有故障分析器(analyzers)能够处理异常,您仍然可以显示完整的自动配置报告,以更好地了解出现的问题。 为此,您需要[启用debug属性](http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#boot-features-external-config)或启用org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer的[DEBUG日志](http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#boot-features-custom-log-levels)。
例如,如果使用java -jar运行应用程序,则可以按如下方式启用 debug:
```
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
```
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#232-自定义banner)23.2 自定义Banner
可以通过在您的类路径中添加一个 banner.txt 文件,或者将banner.location设置到banner文件的位置来更改启动时打印的banner。 如果文件有一些不常用的编码,你可以设置banner.charset(默认为UTF-8)。除了文本文件,您还可以将banner.gif,banner.jpg或banner.png图像文件添加到您的类路径中,或者设置一个banner.image.location属性。 图像将被转换成ASCII艺术表现,并打印在任何文字banner上方。
您可以在banner.txt文件中使用以下占位符:
#### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#表231-banner变量)表23.1\. banner变量
| 变量名 | 描述 |
| --- | --- |
| ${application.version} | 在MANIFEST.MF中声明的应用程序的版本号。例如, Implementation-Version: 1.0 被打印为 1.0. |
| ${application.formatted-version} | 在MANIFEST.MF中声明的应用程序版本号的格式化显示(用括号括起来,以v为前缀)。 例如 (v1.0)。 |
| ${spring-boot.version} | 您正在使用的Spring Boot版本。 例如1.5.2.RELEASE。 |
| ${spring-boot.formatted-version} | 您正在使用格式化显示的Spring Boot版本(用括号括起来,以v为前缀)。 例如(v1.5.2.RELEASE)。 |
| ${[Ansi.NAME](http://ansi.name/)} (or ${[AnsiColor.NAME](http://ansicolor.name/)}, ${[AnsiBackground.NAME](http://ansibackground.name/)}, ${[AnsiStyle.NAME](http://ansistyle.name/)}) | 其中NAME是ANSI转义码的名称。 有关详细信息,请参阅 [AnsiPropertySource](https://github.com/spring-projects/spring-boot/tree/v1.5.2.RELEASE/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiPropertySource.java)。 |
| ${application.title} | 您的应用程序的标题在MANIFEST.MF中声明。 例如Implementation-Title:MyApp打印为MyApp。 |
> 如果要以编程方式生成banner,则可以使用SpringApplication.setBanner()方法。 使用org.springframework.boot.Banner 如接口,并实现自己的printBanner() 方法。
您还可以使用spring.main.banner-mode属性来决定是否必须在System.out(控制台)上打印banner,使用配置的logger(log)或不打印(off)。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#233-定制springapplication)23.3 定制SpringApplication
如果SpringApplication默认值不符合您的想法,您可以创建本地实例并进行自定义。 例如,关闭banner:
```
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
```
> 传递给SpringApplication的构造函数参数是spring bean的配置源。 在大多数情况下,这些将引用@Configuration类,但它们也可以引用XML配置或应扫描的包。
也可以使用application.properties文件配置SpringApplication。 有关详细信息,请参见[第24章“外部配置”](http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#boot-features-external-config)。
有关配置选项的完整列表,请参阅[SpringApplication Javadoc](http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/api/org/springframework/boot/SpringApplication.html)。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#234-流式构建-api)23.4 流式构建 API
如果您需要构建一个ApplicationContext层次结构(具有父/子关系的多个上下文),或者如果您只想使用“流式(fluent)”构建器API,则可以使用SpringApplicationBuilder。
SpringApplicationBuilder允许您链式调用多个方法,并包括允许您创建层次结构的父和子方法。
例如:
```
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
```
> 创建ApplicationContext层次结构时有一些限制,例如 Web组件必须包含在子上下文中,并且相同的环境将用于父和子上下文。 有关详细信息,请参阅[SpringApplicationBuilder Javadoc](http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/api/org/springframework/boot/builder/SpringApplicationBuilder.html)。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#235-application-events-and-listeners)23.5 Application events and listeners
除了常见的Spring Framework事件(如 [ContextRefreshedEvent](http://docs.spring.io/spring/docs/4.3.7.RELEASE/javadoc-api/org/springframework/context/event/ContextRefreshedEvent.html))之外,SpringApplication还会发送一些其他应用程序事件。
> 在创建ApplicationContext之前,实际上触发了一些事件,因此您不能在@Bean上注册一个监听器。 您可以通过SpringApplication.addListeners(...) 或SpringApplicationBuilder.listeners(...)方法注册它们。
> 如果您希望自动注册这些侦听器,无论创建应用程序的方式如何,都可以将META-INF / spring.factories文件添加到项目中,并使用org.springframework.context.ApplicationListener引用您的侦听器。 org.springframework.context.ApplicationListener=com.example.project.MyListener
当您的应用程序运行时,事件按照以下顺序发送:
1. ApplicationStartingEvent在运行开始时发送,但在注册侦听器和注册初始化器之后。
2. 当已经知道要使用的上下文(context)环境,并在context创建之前,将发送ApplicationEnvironmentPreparedEvent。
3. ApplicationPreparedEvent在启动刷新(refresh)之前发送,但在加载了bean定义之后。
4. ApplicationReadyEvent在刷新之后被发送,并且处理了任何相关的回调以指示应用程序准备好服务请求。
5. 如果启动时发生异常,则发送ApplicationFailedEvent。
> 一般您不需要使用应用程序事件,但可以方便地知道它们存在。 在内部,Spring Boot使用事件来处理各种任务。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#236-web-环境)23.6 Web 环境
SpringApplication将尝试代表您创建正确类型的ApplicationContext。 默认情况下,将使用AnnotationConfigApplicationContext或AnnotationConfigEmbeddedWebApplicationContext,具体取决于您是否正在开发Web应用程序。
用于确定“Web环境”的算法是相当简单的(基于几个类的存在)。 如果需要覆盖默认值,可以使用setWebEnvironment(boolean webEnvironment)。
也可以通过调用setApplicationContextClass() 对ApplicationContext完全控制。
> 在JUnit测试中使用SpringApplication时,通常需要调用setWebEnvironment()
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#237-访问应用程序参数)23.7 访问应用程序参数
如果您需要访问传递给SpringApplication.run()的应用程序参数,则可以注入org.springframework.boot.ApplicationArguments bean。 ApplicationArguments接口提供对原始String []参数以及解析选项和非选项参数的访问:
```
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"]
}
}
```
> Spring Boot还将向Spring Environment 注册一个CommandLinePropertySource。 这允许您也使用@Value注解注入应用程序参数。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#238-使用applicationrunner或commandlinerunner)23.8 使用ApplicationRunner或CommandLineRunner
SpringApplication启动时如果您需要运行一些特定的代码,就可以实现ApplicationRunner或CommandLineRunner接口。 两个接口都以相同的方式工作,并提供一个单独的运行方法,这将在SpringApplication.run(...)完成之前调用。
CommandLineRunner接口提供对应用程序参数的访问(简单的字符串数组),而ApplicationRunner使用上述的ApplicationArguments接口。
```
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
```
如果定义了若干CommandLineRunner或ApplicationRunner bean,这些bean必须按特定顺序调用,您可以实现org.springframework.core.Ordered接口,也可以使用org.springframework.core.annotation.Order注解。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#239-application-exit)23.9 Application exit
每个SpringApplication将注册一个JVM关闭钩子,以确保ApplicationContext在退出时正常关闭。 可以使用所有标准的Spring生命周期回调(例如DisposableBean接口或@PreDestroy注释)。
另外,如果希望在应用程序结束时返回特定的退出代码,那么bean可以实现org.springframework.boot.ExitCodeGenerator接口。
### [](file:///C:/Users/geekidentity/AppData/Local/Youdao/YNote/markdown/index.html#2310-管理功能)23.10 管理功能
可以通过指定spring.application.admin.enabled属性来为应用程序启用与管理相关的功能。 这会在平台MBeanServer上暴露SpringApplicationAdminMXBean。 您可以使用此功能来远程管理您的Spring Boot应用程序。 这对于任何服务包装器(service wrapper)实现也是有用的。
> 如果您想知道应用程序在哪个HTTP端口上运行,请使用local.server.port键获取该属性。
> 启用此功能时请小心,因为MBean公开了关闭应用程序的方法。
- Part I. Spring Boot 文档
- Part II. 入门指南
- 8. Spring Boot 介绍
- 9. 系统要求
- 10. 安装 Spring Boot
- 11. 开发您的第一个Spring Boot应用程序
- 12. 接下来应该读什么
- Part III. 使用 Spring Boot
- 13. 构建系统
- 14. 构建代码
- 15. 配置类
- 16. 自动配置
- 17. Spring Beans 和 依赖注入
- 18. 使用@SpringBootApplication注解
- 19. 运行你的应用程序
- 20. 开发工具
- 21. 包装您的应用程序到生产环境
- 22. 接下来应该读什么
- Part IV. Spring Boot 功能
- 23. SpringApplication
- 24. 外部配置
- 25. 配置文件(Profiles)
- 26. 日志
- 27. 开发Web应用程序
- 28. Security
- 29. 使用SQL数据库