Spring boot-(3) Spring Boot特性1
本节将深入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的更多相关文章
- Spring Boot 2.0 新特性和发展方向
以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...
- Spring Boot 2(一):Spring Boot 2.0新特性
Spring Boot 2(一):Spring Boot 2.0新特性 Spring Boot依赖于Spring,而Spring Cloud又依赖于Spring Boot,因此Spring Boot2 ...
- 【2.0新特性】Spring Boot 2.0新特性
以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...
- Spring Boot实践——Spring Boot 2.0 新特性和发展方向
出自:https://mp.weixin.qq.com/s/EWmuzsgHueHcSB0WH-3AQw 以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Jav ...
- Spring Boot 2.0 新特性
这是一篇总结文章,主要收集 Spring Boot 2.0 相对于 Spring Boot 1.x 的新特性,本章节并不提供实践性质的源代码.在 Spring Boot 系列文章中会持续退出实践章节. ...
- 「Spring Boot 2.4 新特性」启动耗时详细监控
背景 Spring Boot 项目随着项目开发过程中引入中间件数量的增加,启动耗时 逐渐增加. 笔者在 <Spring Boot 2.4.0 正式 GA,全面拥抱云原生>文章评论下发现了 ...
- Spring Boot 2.4 新特性,全新的Cron表达式处理机制
说起 cron 表达式大家一定不陌生,我们常用来作为定时任务执行策略规则. 在 Spring Boot 框架中 cron 表达式主要配合 @Scheduled 注解在应用程序中使用. 在 Spring ...
- 「Spring Boot 2.4 新特性」一键构建Docker镜像
背景 在我们开发过程中为了支持 Docker 容器化,一般使用 Maven 编译打包然后生成镜像,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很方便.docker-maven-plugi ...
- Spring Boot 2.3 新特性优雅停机详解
什么是优雅停机 先来一段简单的代码,如下: @RestController public class DemoController { @GetMapping("/demo") p ...
- 原创 Spring Boot 2.3 新特性分层JAR
背景 在我们实际生产容器化部署过程中,往往会遇到 Docker 镜像很大,部署发布很慢的情况 影响 docker 镜像大小的因素,主要有以下三个方面: 基础镜像的大小 .尽量选择 aphine 作为基 ...
随机推荐
- 使用metasploit进行栈溢出攻击-4
有了漏洞我们就可以进行攻击了.首先我们需要了解metasploit的exploit模块,具体可以看 http://www.offensive-security.com/metasploit-unlea ...
- Data Base mysql备份与恢复
mysql 备份与恢复 为什么要备份: 由于系统使用到了MySQL 数 据库,所以每天的工作,就设计到了MySQL数据库的备份问题.但如果每天手工来做MySQL数据库的定时备份,工作量不说,时间还不 ...
- 算法训练 最大的算式(DP)
问题描述 题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大.因为乘号和加号一共就是N-1个了,所以恰好每两个相邻数字之间都有一个符号 ...
- spoj Longest Common Substring
Longest Common Substring SPOJ - LCS 题意:求两个串的最长公共子串 /* 对一个串建立后缀自动机,用另一个串上去匹配 */ #include<iostream& ...
- CF1117G Recursive Queries
题意:给定一个序列,定义[l, r]的最大值在m处,求f(l, r) = f(l, m - 1) + (r - l + 1) + f(m + 1, r).多次询问.100w. 解:考虑这个区间内每个数 ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_IL和验证
1.IL 基于栈——所有指令压入一个执行栈,并从栈弹出结果. 2.IL 指令无类型——指令会判断栈中操作数的类型,并执行恰当的操作. 3.IL 最大优势——应用程序的健壮性和安全性. 将 IL 编译成 ...
- Django 想要单独执行文件
Django 单独文件执行 文件 我是在项目根目录文件创建的. 配置文件: #!/usr/bin/env python import os import sys if __name__ == & ...
- P3943 星空
传送门 观察题目数据,发现 k ≤ 8 ,可能可以从这里入手解决问题 考虑状态压缩 但是我们每次操作都会让一连串的序列改变,而序列的每个状态都是必须要知道的 很麻烦,所以考虑如何把一段区间表示地简单一 ...
- codeforces 985C Liebig's Barrels(贪心)
题目 题意: 有n * k块木板,每个木桶由k木板组成,每个木桶的容量定义为它最短的那块木板的长度. 任意两个木桶的容量v1,v2,满足|v1-v2| <= d. 问n个木桶容量的最大的和为多少 ...
- Java中的两个类:Desktop和SystemTray
在JDK6中 ,AWT新增加了两个类:Desktop和SystemTray,前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件,用默认应用程序打开或编辑文件(比如 ...