本节将深入Spring Boot的细节,可以学到你想使用的或定制的Spring Boot的主要特性。

1. SpringApplication

SpringApplication类为引导一个Spring应用提供了方便的方法,该Spring应用从main方法开启。通常,你可以通过静态方法SpringApplication.run方法,如下所示:

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

当应用启动时,你可以看到如下类似的输出,默认情况下,INFO级别的日志信息将会展示,包含相关的启动细节,如启动该应用的用户等:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v2.0.0.BUILD-SNAPSHOT 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.servlet.context.AnnotationConfigServletWebServerApplicationContext@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)

(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.

当任何错误分析器均无法处理该异常时,你仍然可以显示全部鉴定报告,以便更好的理解哪一块的错误。如果这样做的话,需要为"org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener"启用debug属性或DEBUG日志级别。例如,如果使用java -jar运行程序时,可以按如下命令启用debug属性:

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

(2) 自定义横幅

启动程序时打印的横幅如"Spring"可以进行修改,需要通过增加banner.txt文件到classpath或者设置banner.location属性指定该文件的位置。如果该文件非UTF-8编码,则你需要设置banner.charset。除了文本文件,你也可以增加banner.gif, banner.jpg或banner.png图片到classpath中,或者设置banner.image.location属性。图片将会被转换为ASCII码形式进行展现,并且展现在任何的文本横幅之上。

在banner.txt文件中,你可以使用如下的占位符:

变量 含义
${application.version} 应用的版本号,如MANIFEST.MF所声明的。例如:Implemention-Version: 1.0 将会显示1.0
${application.formatted-version} 与${application.version}类似,但会被以v开头进行格式化显示,如:v1.0
${spring-boot.version} Spring Boot的版本,如2.0.0.BUILD-SNAPSHOT。
${spring-boot.formatted-version} 以v开头格式化显示Spring Boot的版本,如v2.0.0.BUILD-SNAPSHOT
${Ansi.NAME}, ${AnsiColor.NAME}
${AnsiBackground.NAME},
${AnsiStyle.NAME}
该四个关系等价,NAME表示ANSI转移码的名称
${application.title} 应用的名称,如MANIFEST.MF中所示,如:Implementation-Title: MyApp将打印MyApp

注意:也可以通过调用SpringApplication.setBanner(Banner banner)方法设置横幅信息,其中的banner可通过调用org.springframework.boot.Banner接口并实现printBanner()方法进行实现。

你也可使用spring.main.banner-mode属性来决定横幅是打印在标准输出窗口(console), 输出到配置的日志log中(log),亦或是禁止生成(off)。

打印的banner将注册为单例bean对象,并且在springBootBanner名称之下。

(3) 自定义SpringApplication

如果默认的SpringApplication类不适合你的口味,你可以创建局部实例并定制该实例加以替代。例如,如下的关闭banner:

public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}

你也可以通过application.properties文件对SpringApplication进行配置。

(4) 流畅的Builder API

如果你需要构建一个ApplicationContext层级,或者你更倾向于使用流畅的构建API,你可以使用SpringApplicationBuilder. SpringApplicationBuilder可以使你连接多个方法调用,且包含parent及child方法使你创建一个层级关系,如下所示:

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

注意:当创建ApplicationContext层级时,有一些限制。例如,Web组件必须包含在child上下文中,相同的Environment均用于parent和child上下文中。

(5) 应用事件和监听器

除了常用的如ContextRefreshedEvent等Spring框架的事件,一个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) 一个ApplicationEnvironmentPrepareEvent将会在Environment在上下文使用时发送,但在该上下文的创建之后。

3) 一个ApplicationPrepareEvent在刷新开始前发送,但在bean定义加载之后。

4) 一个ApplicationReadyEvent在刷新及任何相关回调处理之后调用,为了通知应用已经准备好服务请求。

5) 一个ApplicationFailedEvent将会被发送,如果启动时存在异常。

注意:通常你不会使用应用事件,但知道他们的存在是有益的。本质上,Spring Boot使用事件处理很多任务。

应用事件通过Spring框架的事件发布机制进行发送。该部分机制中,确保一个事件发布到child上下文的监听器时,也会发布到parent上下文的监听器。这种情况产生的结果就是,如果你的应用使用SpringApplication实例的层级关系,一个监听器可能会接收到多个同类型的应用事件的实例。

为了允许你的监听器可以区别来自其本身上下文的事件还是来自后代上下文的事件,应该请求它的应用上下文被注入,然后比较注入的上下文和该事件的上下文。上下文的注入两种方法实现:1) 通过实现ApplicationContextAware类;2)如果监听器是一个bean,则使用@Autowired注解。

(6) Web环境

SpringApplication尝试在你的立场创建ApplicationContext的正确类型。默认情况下,AnnotationConfigApplicationContext或AnnotationConfigServletWebServerApplicationContext将会被使用,取决于你是否在开发一个web应用。

决定web环境的算法相当简单(基于当前的几个类)。如果你想覆盖默认情况,可以使用setWebEnvironment(boolean webEnvironment)。

也可以完全控制ApplicationContext的类型,通过调用setApplicationContextClass()方法。

注意:当在JUnit单元测试中使用SpringApplication时,通常要求调用setWebEnvironment(false)。

(7) 访问应用参数

如果你想访问传入SpringApplication.run()方法中的应用参数时,你可以注入一个org.soringframework.boot.ApplicationArguments bean。该ApplicationArguments接口可以为原生的string[]参数,以及解析的option和non-option参数提供访问。

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.stereotype.Component; @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环境中注册了CommandLinePropertySource。这使得你可以通过使用@Value注解来注入单个应用程序参数。

(8) 使用ApplicationRunner或CommandLineRunner

如果你想在SpringApplication开启时,运行一些特殊的代码,你可以实现ApplicationRunner或CommandLineRunner接口。两个接口工作方式相同, 均提供一个单独的run方法,该方法在SpringApplication.run()结束时将被调用。

CommandLineRunner接口提供应用程序参数string[]的访问,ApplicationRunner使用之前所说的ApplicationArguments接口。

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component; @Component
public class MyBean implements CommandLineRunner{
public void run(String... args) throws Exception { }
}

如果定义的多个CommandLineRunner或ApplicationRunner beans必须以指定的顺序调用,可以通过如下两种方法实现:1) 实现org.springframework.core.Ordered接口 2) 使用org.springframework.core.annotation.Order注解。

(9) 程序退出

每个SpringApplicaion为JVM注册了一个关闭钩子,用于确保ApplicationContext退出时可以平和地关闭。所有标准Spring生命周期的回调均可以使用,如DisposableBean接口或@PreDestory注解。

此外,当SpringApplication.exit()调用时,如果beans想要返回特殊的退出代码,可以实现org.springframework.boot.ExitCideGenerator接口。该退出代码然后可以传入System.exit()来作为状态码返回,如下例所示:

import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean; @SpringBootApplication
public class ExitCodeApplication { @Bean
public ExitCodeGenerator exitCodeGenerator(){
return () -> 42;
} public static void main(String[] args) {
System.exit(SpringApplication
.exit(SpringApplication.run(ExitCodeApplication.class, args)));
}
}

此外,ExitCodeGenerator接口也可用于实现异常。当异常发生时,Spring Boot可返回基于实现getExitCode()方法提供的退出代码。

(10) 管理特性

通过指定spring.application.admin.enabled属性,即可使用管理相关的特性。这将在MBeanServer平台上公开SpringApplicationAdminMXBean。你可以使用该特性来远程管理你的Spring Boot应用。这个特性将有益于任务服务的封装实现。

注意:

1) 如果你想知道当前程序运行于哪个HTTP端口,你可以通过local.server.port属性得到。

2) 小心使用该特性,因为MBean公开了关闭该应用程序的方法。

Spring boot-(3) Spring Boot特性1的更多相关文章

  1. Spring Boot 2.0 新特性和发展方向

    以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...

  2. Spring Boot 2(一):Spring Boot 2.0新特性

    Spring Boot 2(一):Spring Boot 2.0新特性 Spring Boot依赖于Spring,而Spring Cloud又依赖于Spring Boot,因此Spring Boot2 ...

  3. 【2.0新特性】Spring Boot 2.0新特性

    以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...

  4. Spring Boot实践——Spring Boot 2.0 新特性和发展方向

    出自:https://mp.weixin.qq.com/s/EWmuzsgHueHcSB0WH-3AQw 以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Jav ...

  5. Spring Boot 2.0 新特性

    这是一篇总结文章,主要收集 Spring Boot 2.0 相对于 Spring Boot 1.x 的新特性,本章节并不提供实践性质的源代码.在 Spring Boot 系列文章中会持续退出实践章节. ...

  6. 「Spring Boot 2.4 新特性」启动耗时详细监控

    背景 Spring Boot 项目随着项目开发过程中引入中间件数量的增加,启动耗时 逐渐增加. 笔者在 <Spring Boot 2.4.0 正式 GA,全面拥抱云原生>文章评论下发现了 ...

  7. Spring Boot 2.4 新特性,全新的Cron表达式处理机制

    说起 cron 表达式大家一定不陌生,我们常用来作为定时任务执行策略规则. 在 Spring Boot 框架中 cron 表达式主要配合 @Scheduled 注解在应用程序中使用. 在 Spring ...

  8. 「Spring Boot 2.4 新特性」一键构建Docker镜像

    背景 在我们开发过程中为了支持 Docker 容器化,一般使用 Maven 编译打包然后生成镜像,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很方便.docker-maven-plugi ...

  9. Spring Boot 2.3 新特性优雅停机详解

    什么是优雅停机 先来一段简单的代码,如下: @RestController public class DemoController { @GetMapping("/demo") p ...

  10. 原创 Spring Boot 2.3 新特性分层JAR

    背景 在我们实际生产容器化部署过程中,往往会遇到 Docker 镜像很大,部署发布很慢的情况 影响 docker 镜像大小的因素,主要有以下三个方面: 基础镜像的大小 .尽量选择 aphine 作为基 ...

随机推荐

  1. Gazebo学习随记5 杂记

    模拟建筑编辑器 将卫星图导入世界,方便空中机器人模拟 录像和回放 记录筛选 给关节添加力/扭矩  一开始不知道哪里出现了偏差以一动不动,重启就好了 HDF5数据集 代码内省 模型插件   !!!我终于 ...

  2. luogu4449 于神之怒加强版(莫比乌斯反演)

    link 给定n,m,k,计算\(\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)^k\)对1000000007取模的结果 多组数据,T<=2000,1<=N,M,K&l ...

  3. tftp简单文件传输协议搭建

    TFTP 简单文件传输协议     安装     sudo apt-get install tftp  tftpd openbsd-inetd     需要tftp tftpd openbsd-ine ...

  4. CF709A Juicer 模拟

    Kolya is going to make fresh orange juice. He has n oranges of sizes a1, a2, ..., an. Kolya will put ...

  5. [USACO09OPEN]牛的数字游戏Cow Digit Game 博弈

    题目描述 Bessie is playing a number game against Farmer John, and she wants you to help her achieve vict ...

  6. 黑马MySQL数据库学习day04 MySQL变量 存储过程 用户和授权管理

    /* MySQL中的变量局部变量,用户变量,会话变量和全局变量. 用户变量不用定义,直接使用. 1.用户变量赋值 set @xxx = 值; 2.查询 select @xxx; 语法帮助: 过程保存在 ...

  7. mysql 备份时间 %date~0,4%和 %time~0,2%等用法详解

    比如在windowscmd命令行窗口执行date命令后这个环境变量的值为 当前日期:2014-09-01 星期六 或2014/09/01 周六 那么如下的各个操作的意义如下:%date:~0,4% 表 ...

  8. C语言中函数声明、形参、实参

    函数原型: 原型prototype是函数的声明:描述了函数的返回值与参数: 函数原型说明了两点: 1.该函数的返回值 2.该函数的参数及其类型 ++++++++++++++++++++++++++++ ...

  9. Common Subsequence(最长公共子序列)

    A subsequence of a given sequence is the given sequence with some elements (possible none) left out. ...

  10. Codeforces Round #339 (Div. 2) A

    Description Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, which ...