本节将深入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. C#.Net使用正则表达式抓取百度百家文章列表

    工作之余,学习了一下正则表达式,鉴于实践是检验真理的唯一标准,于是便写了一个利用正则表达式抓取百度百家文章的例子,具体过程请看下面源码: 一:获取百度百家网页内容 public List<str ...

  2. C#中IDisposable的用法-垃圾回收

    在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...

  3. 浅谈chainer框架

    一 chainer基础 Chainer是一个专门为高效研究和开发深度学习算法而设计的开源框架. 这篇博文会通过一些例子简要地介绍一下Chainer,同时把它与其他一些框架做比较,比如Caffe.The ...

  4. Binder学习笔记(七)—— ServiceManager如何响应addService请求

    有了<ServiceManager如何响应checkService请求>的探索,研究addService就轻车熟路了,中间过程不再多说,仅把关键节点列出: frameworks/nativ ...

  5. 【OD深入学习】Java多线程面试题

    一.参考文章 1. Java线程面试题 Top 50 2. Java面试——多线程面试题 3. JAVA多线程和并发基础面试问答 4. 15个顶级Java多线程面试题及回答 二.逐个解答 三.一语中的 ...

  6. 模仿 spring IOC Annotation版自动装配

    spring 有两大核心 IOC和AOP.  IOC (inversion of control) 译为 控制反转,也可以称为 依赖注入 ; AOP(Aspect Oriented Programmi ...

  7. [ZJOI2009]狼和羊的故事 BZOJ1412

    题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈 ...

  8. Palindromes _easy version(reverse)

    Problem Description “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串.请写一个程序判断读入的字符串是否是“回文”.   Input 输入包 ...

  9. Qt 学习之路 2(16):深入 Qt5 信号槽新语法

    Qt 学习之路 2(16):深入 Qt5 信号槽新语法  豆子  2012年9月19日  Qt 学习之路 2  53条评论 在前面的章节(信号槽和自定义信号槽)中,我们详细介绍了有关 Qt 5 的信号 ...

  10. (转)接口自动化测试之http请求实践总结

    一.接口测试的基本思路 1.确定要测试接口的请求类型.接口是get请求还是post请求. 2.确定接口的参数.需要传输的参数有哪些,类型分别是什么,都有哪些要求等. 3.按照参数要求构造请求需要的参数 ...