Spring Boot - 自定义 Banner 图案
我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复【资料】,即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板。
前言
我们在启动 Spring Boot 项目时,默认会在控制台打印 Spring
logo 和版本等信息,如下:
这就是 Spring Boot 的 Banner 打印功能,其实我们可以自定义打印的 banner ,也可以禁用和启用打印 banner 功能。在真实项目中,我们一般不会去自定义 banner 图案,它其实就是项目启动时打印图案或者文字而已,没实际意义。推荐在自己个人项目玩玩这个彩蛋即可,顺便简单了解下它内部实现原理。
比如,自定义一个 banner 之后,项目启动控制台打印如下所示:
实现原理
Spring Boot 有一个接口 org.springframework.boot.Banner
专门实现这个操作。要想自定义打印 banner ,只要自定义一个类实现这个接口,重写 printBanner
方法进行打印即可。Springboot 项目启动时,会创建我们的实现类对象,并调用对象的 printBanner
方法。
package org.springframework.boot;
import java.io.PrintStream;
import org.springframework.core.env.Environment;
/**
* Interface class for writing a banner programmatically.
* 用于以编程方式编写 banner 的接口类
* @since 1.2.0
*/
@FunctionalInterface
public interface Banner {
/**
* Print the banner to the specified print stream.
* 将 banner 打印到指定的打印流。
* @param environment the spring environment
* @param sourceClass the source class for the application
* @param out the output print stream
*/
void printBanner(Environment environment, Class<?> sourceClass, PrintStream out);
// 用于配置Banner的的枚举值
enum Mode {
// 关闭 banner 打印
OFF,
// 打印 banner 到 控制台
CONSOLE,
// 打印 banner 到日志文件
LOG
}
}
默认 Banner 实现类
Springboot 已经有几个自带的 Banner 实现类,Springboot 启动时会根据条件选择不同的 Banner 实现类进行打印 banner 信息。主要是 ImageBanner
,ResourceBanner
,SpringBootBanner
这三个实现类。
- 项目启动时,会判断是否某些条件成立(项目中是否存在 banner 文件),成立则创建
ImageBanner
和ResourceBanner
类对象,并且使用它们来打印 banner。 - 如果不成立检查是否存在我们自定义的 Banner 实现类
fallbackBanner
,如果存在则使用它来打印 banner 图案。 - 否则,则使用默认的
SpringBootBanner
实现类来打印 banner,也就是我们经常看到Spring
图案。
// 获取可用的 Banner 实现类
private Banner getBanner(Environment environment) {
Banners banners = new Banners();
banners.addIfNotNull(getImageBanner(environment));
banners.addIfNotNull(getTextBanner(environment));
if (banners.hasAtLeastOneBanner()) {
return banners;
}
if (this.fallbackBanner != null) {
return this.fallbackBanner;
}
// SpringBootBanner 实现类
return DEFAULT_BANNER;
}
ImageBanner
org.springframework.boot.ImageBanner
类是专门加载和打印图片 banner 的。它检查配置文件 application.proeprties
是否有配置的 spring.banner.image.location
变量的值,这个值可用来指定要加载的图片,如果存在则构建 ImageBanner 对象。如果没有配置变量,则还会检查 Classpath
下是否存在以 banner
开头,以 .gif
,.jpg
,.png
结尾的图片文件,如果有也会构建 ImageBanner 对象。
class SpringApplicationBannerPrinter {
static final String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";
static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };
// 获取 ImageBanner 对象
private Banner getImageBanner(Environment environment) {
// 加载 spring.banner.image.location 指定的文件,文件存在则构建 ImageBanner 对象
String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
if (StringUtils.hasLength(location)) {
Resource resource = this.resourceLoader.getResource(location);
return resource.exists() ? new ImageBanner(resource) : null;
}
// 查找 banner.gif,banner.jpg,banner.png 文件
for (String ext : IMAGE_EXTENSION) {
Resource resource = this.resourceLoader.getResource("banner." + ext);
if (resource.exists()) {
return new ImageBanner(resource);
}
}
return null;
}
}
ResourceBanner
org.springframework.boot.ResourceBanner
类是专门加载和打印字符 banner 的。它检查配置文件 application.proeprties
是否有配置的 spring.banner.location
变量的值,这个值可用来指定要加载的文件,如果存在则构建 ResourceBanner 对象。如果没有配置变量,则还会检查资源路径下是否存在 banner.txt
文件,如果存在也会构建 ResourceBanner 对象。
class SpringApplicationBannerPrinter {
static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
static final String DEFAULT_BANNER_LOCATION = "banner.txt";
// 获取 ResourceBanner 对象
private Banner getTextBanner(Environment environment) {
String location = environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION);
Resource resource = this.resourceLoader.getResource(location);
if (resource.exists()) {
return new ResourceBanner(resource);
}
return null;
}
}
如果想要自定义 banner,我们一般在项目的 resources 资源目录下创建 banner.txt
文件,然后在里面填入我们想要的打印的文字内容即可。例如我在 banner.txt 文件中填充了 Chen Pi
内容,然后启动项目。
SpringBootBanner
如果项目没有设置以上两种自定义的 banner(ImageBanner 和 ResourceBanner),则默认情况下,会使用 SpringBootBanner 实现类打印 banner ,也就是我们启动 Springboot 项目时在控制台看到的打印 Spring
图案。源码如下:
package org.springframework.boot;
import java.io.PrintStream;
import org.springframework.boot.ansi.AnsiColor;
import org.springframework.boot.ansi.AnsiOutput;
import org.springframework.boot.ansi.AnsiStyle;
import org.springframework.core.env.Environment;
/**
* Default Banner implementation which writes the 'Spring' banner.
*/
class SpringBootBanner implements Banner {
// 这个就是我们启动 Springboot 项目时在控制台看到的图案
private static final String[] BANNER = { "", " . ____ _ __ _ _",
" /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\", "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
" \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )", " ' |____| .__|_| |_|_| |_\\__, | / / / /",
" =========|_|==============|___/=/_/_/_/" };
private static final String SPRING_BOOT = " :: Spring Boot :: ";
private static final int STRAP_LINE_SIZE = 42;
@Override
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream printStream) {
for (String line : BANNER) {
printStream.println(line);
}
String version = SpringBootVersion.getVersion();
version = (version != null) ? " (v" + version + ")" : "";
StringBuilder padding = new StringBuilder();
while (padding.length() < STRAP_LINE_SIZE - (version.length() + SPRING_BOOT.length())) {
padding.append(" ");
}
printStream.println(AnsiOutput.toString(AnsiColor.GREEN, SPRING_BOOT, AnsiColor.DEFAULT, padding.toString(),
AnsiStyle.FAINT, version));
printStream.println();
}
}
实现 Banner 类
前面说我们可以实现 Banner 类,重写打印方法,实现自定义 banner 打印功能。
package com.chenpi;
import java.io.PrintStream;
import org.springframework.boot.Banner;
import org.springframework.core.env.Environment;
/**
* @Description 自定义 Banner 实现类
* @Author Mr.nobody
* @Date 2021/6/4
* @Version 1.0
*/
public class MyBanner implements Banner {
@Override
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
String banner = " .__ .__ \n"
+ " ____ | |__ ____ ____ ______ |__|\n"
+ "_/ ___\\| | \\_/ __ \\ / \\ \\____ \\| |\n"
+ "\\ \\___| Y \\ ___/| | \\ | |_> > |\n"
+ " \\___ >___| /\\___ >___| / | __/|__|\n"
+ " \\/ \\/ \\/ \\/ |__| ";
out.println(banner);
}
}
创建自定义的 Banner 实现类对象,设置到 SpringApplication
类对象的 banner 属性,最终这个属性的值会会被赋值到 SpringApplicationBannerPrinter
对象的 fallbackBanner
属性中,感兴趣的可以启动 debug 跟踪下。
package com.chenpi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootBannerApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SpringBootBannerApplication.class);
// 设置自定义 Banner
springApplication.setBanner(new MyBanner());
// 启动 SpringBoot
springApplication.run(args);
}
}
Banner 样式控制
文章一开始的佛祖图形,你会发现是翠绿色的。其实 Springboot 支持我们修改 banner 的颜色,字体斜体,粗体等样式。SpringBoot 为我们提供了三个枚举类来设定这些样式。
- AnsiColor:设定字符的前景色;参考
org.springframework.boot.ansi.AnsiColor
枚举类。 - AnsiBackground:设定字符的背景色;参考
org.springframework.boot.ansi.AnsiBackground
枚举类。 - AnsiStyle:设定字符的加粗、斜体、下划线等等;参考
org.springframework.boot.ansi.AnsiStyle
枚举类。
而且,在 banner.txt 文件中还可以引用一些全局变量,例如:
- ${spring-boot.version}:Spring Boot 版本号;
- ${spring-boot.formatted-version}:格式化后的 Spring Boot 版本号信息。
- ${application.version}:MANIFEST.MF 文件中的版本号;
- ${application.formatted-version}:格式化后的 MANIFEST.MF 文件中的版本号信息;
不仅如此,还可以引用我们在配置文件 application.properties
中定义的变量,例如在配置文件中定义了如下变量:
application.auth=chenpi
定义的 banner.txt 文件内容如下:
${AnsiColor.BRIGHT_GREEN}
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////
${AnsiColor.BRIGHT_CYAN}
Application Version: ${application.version}${application.formatted-version}
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
By -- ${application.auth}
启动项目,会在控制台打印的 banner 如下:
Banner 模式
在 Banner 接口中有定义一个枚举类,这个枚举定义了配置 Banner 的可能枚举值,如下:
@FunctionalInterface
public interface Banner {
// 用于配置Banner的的枚举值
enum Mode {
// 关闭 banner 打印
OFF,
// 打印 banner 到 控制台
CONSOLE,
// 打印 banner 到日志文件
LOG
}
}
所以我们可以选择关闭 banner,banner 打印到控制台还是日志文件,如下:
package com.chenpi;
import org.springframework.boot.Banner.Mode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootBannerApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SpringBootBannerApplication.class);
// 关闭 banner
springApplication.setBannerMode(Mode.OFF);
// 启动 SpringBoot
springApplication.run(args);
}
}
也可以配置文件中设置此值,如下
spring.main.banner-mode=off
如果启动类跟配置文件中都配置了对banner开关的设置,配置文件中设置的banner开关会优先于启动类中设置的开关。
banner 图生成工具
可能有人会问佛祖的图案怎么编辑出来的,其实网上有很多工具可以根据我们输入的内容或者图片,个性化制作ASCII字符和图案,推荐网址如下:
- 定制化 ASCII 字符:http://network-science.de/ascii/
- 定制化 ASCII 图片:https://www.degraeve.com/img2txt.php
Spring Boot - 自定义 Banner 图案的更多相关文章
- Spring Boot自定义Banner
在2016年的最后一天,借用Spring Boot的Banner向各位程序猿同仁们问候一声:Happy New Year. 接下来我们就来介绍一下这个轻松愉快的自定义banner功能.实现的方式非常简 ...
- Spring Boot 自定义 Banner 教程
我们在启动 SpringBoot 时,控制台会打印 SpringBoot Logo 以及版本信息.有的时候我们需要自己弄个有个性的文本图片.Spring Boot 为我们提供了自定义接口. . ___ ...
- Spring boot 自定义banner的在线制作
目前工作不是很忙,利用闲暇的时间,在给自己不断地充电,提升自己的技术实力. 目前在做一个基于Spring Boot2.x+webmagic+quartz的爬虫项目[hotDog]https://git ...
- Spring boot 自定义banner
Spring Boot启动的时候会在命令行生成一个banner,其实这个banner是可以自己修改的,本文将会将会讲解如何修改这个banner. 首先我们需要将banner保存到一个文件中,网上有很多 ...
- Spring Boot定制启动图案
启动图案 Spring Boot在启动的时候会显示一个默认的Spring的图案,对应的类为SpringBootBanner. . ____ _ __ _ _ /\\ / ___'_ __ _ _(_) ...
- spring boot自定义线程池以及异步处理
spring boot自定义线程池以及异步处理@Async:什么是线程池?线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使 ...
- Spring Boot自定义配置与加载
Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...
- Spring Boot 2.X(四):Spring Boot 自定义 Web MVC 配置
0.准备 Spring Boot 不仅提供了相当简单使用的自动配置功能,而且开放了非常自由灵活的配置类.Spring MVC 为我们提供了 WebMvcConfigurationSupport 类和一 ...
- Spring Boot自定义Redis缓存配置,保存value格式JSON字符串
Spring Boot自定义Redis缓存,保存格式JSON字符串 部分内容转自 https://blog.csdn.net/caojidasabi/article/details/83059642 ...
随机推荐
- Parentheses Balance UVA - 673
You are given a string consisting of parentheses () and []. A string of this type is said to be corr ...
- 介绍一款能取代 Scrapy 的 Python 爬虫框架 - feapder
1. 前言 大家好,我是安果! 众所周知,Python 最流行的爬虫框架是 Scrapy,它主要用于爬取网站结构性数据 今天推荐一款更加简单.轻量级,且功能强大的爬虫框架:feapder 项目地址: ...
- [源码分析]并行分布式任务队列 Celery 之 子进程处理消息
[源码分析]并行分布式任务队列 Celery 之 子进程处理消息 0x00 摘要 Celery是一个简单.灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度.在前 ...
- KMP(梅开三度之数据结构详解版
前言 KMP算法是一种字符串匹配算法,其重中之重是next数组的构建,其代码的简洁与神奇使其广受关注. 但不难发现,acm中学到的KMP和数据结构里面学到的KMP并不一样o(︶︿︶)o 之前我写过ac ...
- 5403. Find the Kth Smallest Sum of a Matrix With Sorted Rows
You are given an m * n matrix, mat, and an integer k, which has its rows sorted in non-decreasing or ...
- ASP检测客户是否取消微信公众号
有时因为项目内需要用到检测客户是否已经取消关注微信公众号,只有没被取消执行相关模板信息发送.图文信息发送.视频语音等信息发送给客户才有意义.也可以知道多少客户还在我们的微信公众号关注内.方便后期做公众 ...
- pyqt5 多线程+定时器+读取本地图片
前言 一个程序界面有多个button 按钮时,单击一个按钮,若此按钮对应的信号正在执行,且还未执行完毕: 此时再次单击另外一个按钮,就会出现假死状态. 这个时候我们就需要使用 多线程去解决 多线程+定 ...
- 初中级php程序员面试时常见问题整理
初中级php程序员面试问题收集 感悟 有时候草率给出一个答案,比思而无果更糟糕 php基础 php的数据类型 php数据类型的转换 php魔术方法 php 的trait的概念及特点 php 虚拟类和接 ...
- jQuery监控键盘事件
<!doctype html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- hdu4662 简单搜索打表
题意: 给你一个初始串"MI",这个串有三种操作, (1)M后卖弄可以直接复制 ,MI -> MII (2)三个III可以变成一个U,MUIII -> MUU ...