我是陈皮,一个在互联网 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 信息。主要是 ImageBannerResourceBannerSpringBootBanner 这三个实现类。

  1. 项目启动时,会判断是否某些条件成立(项目中是否存在 banner 文件),成立则创建 ImageBannerResourceBanner 类对象,并且使用它们来打印 banner。
  2. 如果不成立检查是否存在我们自定义的 Banner 实现类 fallbackBanner,如果存在则使用它来打印 banner 图案。
  3. 否则,则使用默认的 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 为我们提供了三个枚举类来设定这些样式。

  1. AnsiColor:设定字符的前景色;参考 org.springframework.boot.ansi.AnsiColor 枚举类。
  2. AnsiBackground:设定字符的背景色;参考 org.springframework.boot.ansi.AnsiBackground 枚举类。
  3. AnsiStyle:设定字符的加粗、斜体、下划线等等;参考 org.springframework.boot.ansi.AnsiStyle 枚举类。

而且,在 banner.txt 文件中还可以引用一些全局变量,例如:

  1. ${spring-boot.version}:Spring Boot 版本号;
  2. ${spring-boot.formatted-version}:格式化后的 Spring Boot 版本号信息。
  3. ${application.version}:MANIFEST.MF 文件中的版本号;
  4. ${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字符和图案,推荐网址如下:

Spring Boot - 自定义 Banner 图案的更多相关文章

  1. Spring Boot自定义Banner

    在2016年的最后一天,借用Spring Boot的Banner向各位程序猿同仁们问候一声:Happy New Year. 接下来我们就来介绍一下这个轻松愉快的自定义banner功能.实现的方式非常简 ...

  2. Spring Boot 自定义 Banner 教程

    我们在启动 SpringBoot 时,控制台会打印 SpringBoot Logo 以及版本信息.有的时候我们需要自己弄个有个性的文本图片.Spring Boot 为我们提供了自定义接口. . ___ ...

  3. Spring boot 自定义banner的在线制作

    目前工作不是很忙,利用闲暇的时间,在给自己不断地充电,提升自己的技术实力. 目前在做一个基于Spring Boot2.x+webmagic+quartz的爬虫项目[hotDog]https://git ...

  4. Spring boot 自定义banner

    Spring Boot启动的时候会在命令行生成一个banner,其实这个banner是可以自己修改的,本文将会将会讲解如何修改这个banner. 首先我们需要将banner保存到一个文件中,网上有很多 ...

  5. Spring Boot定制启动图案

    启动图案 Spring Boot在启动的时候会显示一个默认的Spring的图案,对应的类为SpringBootBanner. . ____ _ __ _ _ /\\ / ___'_ __ _ _(_) ...

  6. spring boot自定义线程池以及异步处理

    spring boot自定义线程池以及异步处理@Async:什么是线程池?线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使 ...

  7. Spring Boot自定义配置与加载

    Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...

  8. Spring Boot 2.X(四):Spring Boot 自定义 Web MVC 配置

    0.准备 Spring Boot 不仅提供了相当简单使用的自动配置功能,而且开放了非常自由灵活的配置类.Spring MVC 为我们提供了 WebMvcConfigurationSupport 类和一 ...

  9. Spring Boot自定义Redis缓存配置,保存value格式JSON字符串

    Spring Boot自定义Redis缓存,保存格式JSON字符串 部分内容转自 https://blog.csdn.net/caojidasabi/article/details/83059642 ...

随机推荐

  1. JAVAEE_04_Tomcat服务器

    Tomcat服务器 * 常用的服务器 - WebLogic服务器 WebLogic是美国bea公司出品的一个application server.BEA WebLogic是用于开发.集成.部署和管理大 ...

  2. kubernetes集群证书更新

    kubeadm 默认证书为一年,一年过期后,会导致api service不可用,使用过程中会出现:x509: certificate has expired or is not yet valid. ...

  3. K8S(17)二进制的1.15版本部署hpa自动伸缩

    K8S(17)二进制部署的K8S(1.15)部署hpa功能 目录 K8S(17)二进制部署的K8S(1.15)部署hpa功能 零.参考文件: 一.生成metrics-proxy证书 二.修改apise ...

  4. 域迁移DA | Learning From Synthetic Data: Addressing Domain Shift for Se | CVPR2018

    文章转自:微信公众号「机器学习炼丹术」 作者:炼丹兄(已授权) 联系方式:微信cyx645016617 论文名称:"Learning From Synthetic Data: Address ...

  5. 1036 Boys vs Girls

    This time you are asked to tell the difference between the lowest grade of all the male students and ...

  6. MVC之实现基于token的认证

    安装Nuget包 项目中添加包:dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer 添加认证配置 Startup类中添加如 ...

  7. linux下export命令添加删除环境变量

    Linux export命令参数   功能说明:设置或显示环境变量. 语 法:export [-fnp][变量名称]=[变量设置值] 补充说明:在shell中执行程序时,shell会提供一组环境变量. ...

  8. 硬盘分区形式(MBR、GPT)、系统引导、文件系统、Inode和Block

    目录 MBR和GPT MBR的局限性 GPT的优势 主分区.扩展分区和逻辑分区 挂接卷 Legacy.UEFI引导和GRUB引导 文件系统(FAT16.32.NTFS和EXT2.3.4.Xfs.Tmp ...

  9. Ubuntu Linux 学习篇 配置DHCP服务器

    isc-dhcp-server 动态主机配置协议是一个局域网的网络协议.指的是由服务器控制一段IP地址范围,客户机登录服务器时就可以自动获得服务器分配的IP地址和子网掩码.首先, DHCP服务器必须是 ...

  10. 2021最新Java面试题全集-20210326版

    在手撕了数千道网络流传的面试题,外加十多个不眠之夜, 终于从里面精心挑选出约500道题目, 做为大家求职.跳槽前复习准备面试使用. 一:挑选题目的原则: 常考的.常被面试问到的 题目有一定的深度和难度 ...