20.md 12.8 KB
Newer Older
W
mkdocs  
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
# 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公开了关闭应用程序的方法。