教你怎么用Springboot自定义Banner图案

网友投稿 259 2022-10-20


教你怎么用Springboot自定义Banner图案

一、前言

我们在启动 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 这三个实现类。

1.项目启动时,会判断是否某些条件成立(项目中是否存在 banner 文件),成立则创建 ImageBanner 和 ResourceBanner 类对象,并且使用它们来打印 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 //

// ____/`---'\____ //

// .' \\| |// `. //

// / \\||| : |||// \ //

// / _||||| -:- |||||- \ //

// | | \\\ - /// | | //

// | \_| ''\---/'' | | //

// \ .-\__ `-` ___/-. / //

// ___`. .' /--.--\ `. . ___ //

// ."" '< `.___\_<|>_/___.' >'"". //

// http:// | | : `- \`.;`\ _ /`;.`/ - ` : | | //

// \ \ `-. \_ __\ /__ _/ .-` / / //

// ========`-.____`-.___\_____/___.-`____.-'======== //

// `=---=' //

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //

// 佛祖保佑 永不宕机 永无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 springAhttp://pplication = 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://degraeve.com/img2txt.php


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:万兆应用是选屏蔽布线还是非屏蔽布线
下一篇:走近屏蔽布线
相关文章

 发表评论

暂时没有评论,来抢沙发吧~