Spring Boot 2.0.0参考手册_中文版_Part IV_23

文章作者:Tyan
博客:noahsnail.com  |  CSDN  |  简书

Part IV. Spring Boot特性

这一部分进入Spring Boot细节部分。在这部分你会了解到你想使用和定制的一些重要特性。如果你还没准备好,你可以阅读第二部分“Getting started”和第三部分“Using Spring Boot”,可以对基础知识有个较好的认识。

23. SpringApplication

SpringApplication提供了一种很方便的方式来引导Spring应用,Spring应用可以从main()方法中启动。许多情况下你可以委托给静态方法SpringApplication.run

public static void main(String[] args) {
    SpringApplication.run(MySpringConfiguration.class, args);
}

当你的应用启动时你应该看到类似于下面的东西:

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::   v1.4.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日志信息,包括一些相关的启动细节例如启动应用的用户。

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实现,你可以很容易添加自己的FailureAnalyzer实现。

如果没有失败分析器能处理这个异常,你仍可以显示完整的自动配置报告,从而更好的理解什么地方出问题了。为了实现这个你需要启用debug属性或启用org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializerDEBUG日志。

例如,如果你使用java -jar运行应用,你可以用下面的形式启用debug属性:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

23.2 定制Banner

启动时打印的标语可以通过在classpath中添加一个banner.txt文件或者将banner.location设置为banner.txt文件的位置来修改。如果文件是一种不常见的编码方式,你可以设置banner.charset(默认是UTF-8)。除了文本文件之外,你也添加一个banner.gifbanner.jpgbanner.png图像文件到classpath中,或者设置一个banner.image.location属性。图像将被转换成ASCII艺术表示并打印在文本标语之上。

banner.txt内部你可以使用下面的任何占位符:

Table 23.1. Banner变量

Variable Description
${application.version} 你的应用的版本号在MANIFEST.MF中声明。 例如Implementation-Version: 1.0打印成1.0.
${application.formatted-version} MANIFEST.MF中的声明的应用版本号进行格式化显示(加上前缀v并用括号包裹)。例如(v1.0)
${spring-boot.version} 你使用的Spring Boot版本。例如1.4.2.RELEASE.
${spring-boot.formatted-version} 你使用的Spring Boot版本进行格式化显示加上前缀v并用括号包裹)。例如(v1.4.2.RELEASE)
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}) NAME是ANSI转义码的名字。更多细节请看AnsiPropertySource
${application.title} MANIFEST.MF中声明的应用标题。例如Implementation-Title: MyApp打印成MyApp.

如果你想自动生成一个标语你可以使用SpringApplication.setBanner(…​)方法。使用org.springframework.boot.Banner接口并实现你自己的printBanner()方法。

你也可以使用spring.main.banner-mode属性来决定标语是否必须在System.out(控制台)上输出,使用配置的日志(log)或一点也不用(off)。

如果你想在你的应用中禁用banner,YAML会将off映射为false,因此要确保添加引用。

spring:
    main:
        banner-mode: "off"

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 beans配置源。在大多数情况下将会引用@Configuration类,但它们也可以引用XML配置或应该扫描的包。

也可以使用application.properties文件配置SpringApplication。更多细节请看24章,『外部配置』。

完整的配置选项列表,请看SpringApplication文档。

23.4 流畅的构建器API

如果你需要构建ApplicationContext分层(多个具有父/子关系的上下文),或者你更喜欢使用fluent的构建器API,你可以使用SpringApplicationBuilder

SpringApplicationBuilder允许你链接多个方法调用,包括允许你创建分层的parentchild方法。

例如:

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);

当创建ApplicationContext分层时有一些限制,例如,子上下文必须包含web组件,父子上下文将使用同一个Environment。更完整的细节请看SpringApplicationBuilder文档。

23.5 应用事件和监听器

除了平常的Spring框架事件之外,例如ContextRefreshedEventSpringApplication会发送一些其它的应用事件。

ApplicationContext创建之前实际上会触发一些事件,因此你不能使用@Bean来注册这些监听器。你可以通过SpringApplication.addListeners(…​)SpringApplicationBuilder.listeners(…​)方法来注册这些监听器。

如果你想自动注册这些监听器,不管上下文的创建方式,你可以在你的工程中添加META-INF/spring.factories文件,并通过org.springframework.context.ApplicationListener作为key来引用你的监听器。

org.springframework.context.ApplicationListener=com.example.project.MyListener

当你的应用运行时,应用事件以下面的顺序发送:

  1. 在运行启动时发送ApplicationStartedEvent,除了监听器和初始化器注册之外,在进行任何处理之前发送。
  2. 当在上下文中使用的Environment已知时,发送ApplicationEnvironmentPreparedEvent,但发送是在上下文创建之前。
  3. 在再刷新启动之前,但在bean定义加载之后,发送ApplicationPreparedEvent
  4. 在再刷新之后,发送ApplicationReadyEvent,任何相关的回调函数都处理完成之后,意味着应用已经准备处理服务请求了。
  5. 如果启动时出现异常,发送ApplicationFailedEvent.

经常你不需要使用应用事件,但知道它们的存在是便利的。Spring Boot内部使用事件来处理大量的任务。

23.6 Web环境

SpringApplication会尝试创建代表你的合适的ApplicationContext类型。默认情况下,会使用AnnotationConfigApplicationContextAnnotationConfigEmbeddedWebApplicationContext,依赖于你是否在开发一个web应用。

使用的决定web environment的算法是相对简单的(基于现有的一些类)。如果你需要覆写默认值你可以使用setWebEnvironment(boolean webEnvironment)

完全控制ApplicationContext类型也是可能的,通过调用setApplicationContextClass(…​)使用。

当在JUnit测试时使用SpringApplication,经常需要调用setWebEnvironment(false)

23.7 访问应用参数

如果你需要访问传进SpringApplication.run(…​)中的应用参数,你可以注入org.springframework.boot.ApplicationArguments bean。ApplicationArguments接口提供了访问原始String[]和转换的optionnon-option参数。

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注解注入单个应对参数。

23.8 使用ApplicationRunner或CommandLineRunner

如果你需要在SpringApplication启动时运行一些特定的代码,你可以实现ApplicationRunnerCommandLineRunner接口。这两个接口以同样方式工作,并有一个单独的run方法,在SpringApplication.run(…​)之前会调用这个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...
    }

}

另外,如果定义的CommandLineRunnerApplicationRunner beans必须以指定顺序调用,你可以实现org.springframework.core.Ordered接口或org.springframework.core.annotation.Order 注解。

23.9 应用退出

为了确保ApplicationContext在关闭时安全退出, 每个SpringApplication都会在JVM中注册一个关闭钩子。所有的标准Spring生命周期回调函数(例如DisposableBean接口,或@PreDestroy注解)都会被使用。

另外,当应用退出时,如果它们想返回一个特定的退出码,beans可以实现org.springframework.boot.ExitCodeGenerator接口。

23.10 Admin功能

如果应用想启用admin相关的功能,可以指定spring.application.admin.enabled属性。这会在平台MBeanServer上暴露SpringApplicationAdminMXBean。你可以使用这个功能远程的管理你的Spring Boot应用。对于任何服务包裹的实现这是很有用的。

如果你想知道应用运行的HTTP接口,通过关键字local.server.port可以得到这个属性。

 

当启用这个功能时要非常小心,因为MBean会暴露一个关闭应用的方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容