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 ...
随机推荐
- Pandas的loc,iloc与ix的用法及区别
1.先来谈一谈loc,loc这个方法就是你有啥我就用啥,你没有的我不用,pandas对象的index,columns有什么,pd.loc[index,column],index就是pd.index的其 ...
- D - D ZOJ - 1151 (字符串操作)
For each list of words, output a line with each word reversed without changing the order of the word ...
- linux下python调用.so文件
前言 使用python 调用Fanuc的动态链路库.so 文件读取数据 环境要求 环境 需求 ubuntu16.04 32位 python3.5 32位 配置 把so文件添加到默认路径 ln -s / ...
- C/C++ 实现VA与FOA之间的转换
PE结构中的地址互转,这次再来系统的复习一下关于PE结构中各种地址的转换方式,最终通过编程来实现自动解析计算,最后将这个功能集成到我的迷你解析器中,本章中使用的工具是上次讲解PE结构文章中制作的CMD ...
- 路由器逆向分析------MIPS系统网络的配置(QEMU)
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/69378333 MIPS系统网络的配置 使用QEMU 模拟正在运行的MIPS系统并 ...
- DVWA之 SQL Injection(Blind)
SQL Injection(Blind) SQL Injection(Blind),即SQL盲注,与一般注入的区别在于,一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法 ...
- POJ3498最大流,枚举终点,企鹅,基础最大流
题意: 有一n个冰块,每个冰块上都有一些企鹅,所有的企鹅要跳到一个冰块上去,但是由于起跳是的后坐力原因导致每个冰块最多条mi次,最后问你所有的企鹅都跳到一个冰块上去的那块冰块可以是哪一块, ...
- PowerShell-3.多线程
$start = Get-Date $task1 = { $vUrl = 'http://img.mottoin.com/wp-content/uploads/2016/09/5-25.png' $v ...
- CTFHub-easy_search
easy_search 玩了好些天,今天做道题找找状态,明天开始肝了 打开是一个登录框 用amdin/admin尝试了一下,提示登陆失败 这里肯定不会是暴力破解,我猜是sql注入,试了万能密码or 1 ...
- Ravindrababu Ravula老师的数据结构与算法
最关键的问题是,作为印度裔,他的英语口音真的真的很好懂!!!而且语速很慢,适合大家学习. 作为一哥热衷于搬砖的小伙,我将他的视频搬运到了B站,大家可以前往我的B站观看,搜索"爱码士Noe&q ...