本节将深入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. java基础之流程控制语句

    一.     分支 1.      三元运算符 ?: 注意:三元运算符虽然简洁但是语法乱,而且必须要有接受者或者直接打印 1.     if else语句 另一种不带括号的写法: if(条件) 语句1 ...

  2. DB2安装步骤

    ##################################DB2的安装########################### ## 安装前准备 ## 关闭内存地址随机化机制 vi /etc/ ...

  3. C++基础学习3:输入和输出(cin和cout)

    在C语言中,通常会在采用格式化输入输出函数printf和scanf用于输入或输出数据或信息.在C++语言中,C语言的这一套输入输出库我们仍能使用,但是C++语言又自定义了一套新的.更容易使用的输入输出 ...

  4. 在线作图工具 Flowchart Maker & Online Diagram Software & Visual Solution

    9款国内外垂直领域的在线作图工具:那些可以替代Visio的应用!-CSDN.NEThttps://www.csdn.net/article/2015-02-12/2823939 Documentsht ...

  5. Xshell连接不上Ubuntu解决方式

    1—— 首先检查一下自己的网络是否正常,如果是插上网线就能用的,就很好:如果是校园网拨号方式上网的,请检查自己是否建立拨号连接. [编辑连接] [添加] PPPOE上网方式选择[DSL]   2—— ...

  6. SprimgMVC学习笔记(六)—— 全局异常的处理

    一.处理思路 springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 系统中异常包括两类:预期异常和运行时异常RuntimeExcept ...

  7. Mybatis学习笔记(六) —— 动态sql

    通过mybatis提供的各种标签方法实现动态拼接sql. 需求:根据性别和名字查询用户 查询sql: SELECT id, username, birthday, sex, address FROM ...

  8. 小a与黄金街道(欧拉函数+快速幂)

    链接:https://ac.nowcoder.com/acm/contest/317/D 来源:牛客网 题目描述 小a和小b来到了一条布满了黄金的街道上.它们想要带几块黄金回去,然而这里的城管担心他们 ...

  9. 云数据库 Redis 缓存 PHP session 变量

    1.安装 phpredis 扩展. wget https://github.com/nicolasff/phpredis/archive/master.zip unzip master.zip cd ...

  10. java TopK算法

    现有一亿个数据,要求从其中找出最小的一万个数,希望所需的时间和空间最小,也就是所谓的topK问题 TopK问题就是从海量的数据中取最大(或最小的)的K个数. TopK问题其实是有线性时间复杂度的解的, ...