教你怎么用Springboot自定義Banner圖案
一、前言
我們?cè)趩?dòng) Spring Boot 項(xiàng)目時(shí),默認(rèn)會(huì)在控制臺(tái)打印 Spring logo 和版本等信息,如下:

這就是 Spring Boot 的 Banner 打印功能,其實(shí)我們可以自定義打印的 banner ,也可以禁用和啟用打印 banner 功能。在真實(shí)項(xiàng)目中,我們一般不會(huì)去自定義 banner 圖案,它其實(shí)就是項(xiàng)目啟動(dòng)時(shí)打印圖案或者文字而已,沒(méi)實(shí)際意義。推薦在自己個(gè)人項(xiàng)目玩玩這個(gè)彩蛋即可,順便簡(jiǎn)單了解下它內(nèi)部實(shí)現(xiàn)原理。
比如,自定義一個(gè) banner 之后,項(xiàng)目啟動(dòng)控制臺(tái)打印如下所示:

二、實(shí)現(xiàn)原理
Spring Boot 有一個(gè)接口 org.springframework.boot.Banner 專門(mén)實(shí)現(xiàn)這個(gè)操作。要想自定義打印 banner ,只要自定義一個(gè)類實(shí)現(xiàn)這個(gè)接口,重寫(xiě) printBanner 方法進(jìn)行打印即可。Springboot 項(xiàng)目啟動(dòng)時(shí),會(huì)創(chuàng)建我們的實(shí)現(xiàn)類對(duì)象,并調(diào)用對(duì)象的 printBanner 方法。
package org.springframework.boot;
import java.io.PrintStream;
import org.springframework.core.env.Environment;
/**
* Interface class for writing a banner programmatically.
* 用于以編程方式編寫(xiě) 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 {
// 關(guān)閉 banner 打印
OFF,
// 打印 banner 到 控制臺(tái)
CONSOLE,
// 打印 banner 到日志文件
LOG
}
}
三、默認(rèn) Banner 實(shí)現(xiàn)類
Springboot 已經(jīng)有幾個(gè)自帶的 Banner 實(shí)現(xiàn)類,Springboot 啟動(dòng)時(shí)會(huì)根據(jù)條件選擇不同的 Banner 實(shí)現(xiàn)類進(jìn)行打印 banner 信息。主要是 ImageBanner,ResourceBanner,SpringBootBanner 這三個(gè)實(shí)現(xiàn)類。
1.項(xiàng)目啟動(dòng)時(shí),會(huì)判斷是否某些條件成立(項(xiàng)目中是否存在 banner 文件),成立則創(chuàng)建 ImageBanner 和 ResourceBanner 類對(duì)象,并且使用它們來(lái)打印 banner。
2.如果不成立檢查是否存在我們自定義的 Banner 實(shí)現(xiàn)類 fallbackBanner,如果存在則使用它來(lái)打印 banner 圖案。
3.否則,則使用默認(rèn)的 SpringBootBanner 實(shí)現(xiàn)類來(lái)打印 banner,也就是我們經(jīng)??吹?Spring 圖案。
// 獲取可用的 Banner 實(shí)現(xiàn)類
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 實(shí)現(xiàn)類
return DEFAULT_BANNER;
}
四、ImageBanner
org.springframework.boot.ImageBanner 類是專門(mén)加載和打印圖片 banner 的。它檢查配置文件 application.proeprties 是否有配置的 spring.banner.image.location 變量的值,這個(gè)值可用來(lái)指定要加載的圖片,如果存在則構(gòu)建 ImageBanner 對(duì)象。如果沒(méi)有配置變量,則還會(huì)檢查 Classpath 下是否存在以 banner 開(kāi)頭,以 .gif,.jpg,.png 結(jié)尾的圖片文件,如果有也會(huì)構(gòu)建 ImageBanner 對(duì)象。
class SpringApplicationBannerPrinter {
static final String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";
static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };
// 獲取 ImageBanner 對(duì)象
private Banner getImageBanner(Environment environment) {
// 加載 spring.banner.image.location 指定的文件,文件存在則構(gòu)建 ImageBanner 對(duì)象
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 類是專門(mén)加載和打印字符 banner 的。它檢查配置文件 application.proeprties 是否有配置的 spring.banner.location 變量的值,這個(gè)值可用來(lái)指定要加載的文件,如果存在則構(gòu)建 ResourceBanner 對(duì)象。如果沒(méi)有配置變量,則還會(huì)檢查資源路徑下是否存在 banner.txt 文件,如果存在也會(huì)構(gòu)建 ResourceBanner 對(duì)象。
class SpringApplicationBannerPrinter {
static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
static final String DEFAULT_BANNER_LOCATION = "banner.txt";
// 獲取 ResourceBanner 對(duì)象
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,我們一般在項(xiàng)目的 resources 資源目錄下創(chuàng)建 banner.txt 文件,然后在里面填入我們想要的打印的文字內(nèi)容即可。例如我在 banner.txt 文件中填充了 Chen Pi 內(nèi)容,然后啟動(dòng)項(xiàng)目。


六、SpringBootBanner
如果項(xiàng)目沒(méi)有設(shè)置以上兩種自定義的 banner(ImageBanner 和 ResourceBanner),則默認(rèn)情況下,會(huì)使用 SpringBootBanner 實(shí)現(xiàn)類打印 banner ,也就是我們啟動(dòng) Springboot 項(xiàng)目時(shí)在控制臺(tái)看到的打印 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 {
// 這個(gè)就是我們啟動(dòng) Springboot 項(xiàng)目時(shí)在控制臺(tái)看到的圖案
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();
}
}
七、實(shí)現(xiàn) Banner 類
前面說(shuō)我們可以實(shí)現(xiàn) Banner 類,重寫(xiě)打印方法,實(shí)現(xiàn)自定義 banner 打印功能。
package com.chenpi;
import java.io.PrintStream;
import org.springframework.boot.Banner;
import org.springframework.core.env.Environment;
/**
* @Description 自定義 Banner 實(shí)現(xiàn)類
* @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);
}
}
創(chuàng)建自定義的 Banner 實(shí)現(xiàn)類對(duì)象,設(shè)置到 SpringApplication 類對(duì)象的 banner 屬性,最終這個(gè)屬性的值會(huì)會(huì)被賦值到 SpringApplicationBannerPrinter 對(duì)象的 fallbackBanner 屬性中,感興趣的可以啟動(dòng) 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);
// 設(shè)置自定義 Banner
springApplication.setBanner(new MyBanner());
// 啟動(dòng) SpringBoot
springApplication.run(args);
}
}
八、Banner 樣式控制
文章一開(kāi)始的佛祖圖形,你會(huì)發(fā)現(xiàn)是翠綠色的。其實(shí) Springboot 支持我們修改 banner 的顏色,字體斜體,粗體等樣式。SpringBoot 為我們提供了三個(gè)枚舉類來(lái)設(shè)定這些樣式。
1.AnsiColor:設(shè)定字符的前景色;參考 org.springframework.boot.ansi.AnsiColor 枚舉類。
2.AnsiBackground:設(shè)定字符的背景色;參考 org.springframework.boot.ansi.AnsiBackground 枚舉類。
3.AnsiStyle:設(shè)定字符的加粗、斜體、下劃線等等;參考 org.springframework.boot.ansi.AnsiStyle 枚舉類。
而且,在 banner.txt 文件中還可以引用一些全局變量,例如:
1.${spring-boot.version}:Spring Boot 版本號(hào);
2.${spring-boot.formatted-version}:格式化后的 Spring Boot 版本號(hào)信息。
3.${application.version}:MANIFEST.MF 文件中的版本號(hào);
4.${application.formatted-version}:格式化后的 MANIFEST.MF 文件中的版本號(hào)信息;
不僅如此,還可以引用我們?cè)谂渲梦募?application.properties 中定義的變量,例如在配置文件中定義了如下變量:
application.auth=chenpi
定義的 banner.txt 文件內(nèi)容如下:
${AnsiColor.BRIGHT_GREEN}
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕機(jī) 永無(wú)BUG //
${AnsiColor.BRIGHT_CYAN}
Application Version: ${application.version}${application.formatted-version}
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
By -- ${application.auth}
啟動(dòng)項(xiàng)目,會(huì)在控制臺(tái)打印的 banner 如下:

九、Banner 模式
在 Banner 接口中有定義一個(gè)枚舉類,這個(gè)枚舉定義了配置 Banner 的可能枚舉值,如下:
@FunctionalInterface
public interface Banner {
// 用于配置Banner的的枚舉值
enum Mode {
// 關(guān)閉 banner 打印
OFF,
// 打印 banner 到 控制臺(tái)
CONSOLE,
// 打印 banner 到日志文件
LOG
}
}
所以我們可以選擇關(guān)閉 banner,banner 打印到控制臺(tái)還是日志文件,如下:
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);
// 關(guān)閉 banner
springApplication.setBannerMode(Mode.OFF);
// 啟動(dòng) SpringBoot
springApplication.run(args);
}
}
也可以配置文件中設(shè)置此值,如下
spring.main.banner-mode=off
如果啟動(dòng)類跟配置文件中都配置了對(duì)banner開(kāi)關(guān)的設(shè)置,配置文件中設(shè)置的banner開(kāi)關(guān)會(huì)優(yōu)先于啟動(dòng)類中設(shè)置的開(kāi)關(guān)。
十、banner 圖生成工具
可能有人會(huì)問(wèn)佛祖的圖案怎么編輯出來(lái)的,其實(shí)網(wǎng)上有很多工具可以根據(jù)我們輸入的內(nèi)容或者圖片,個(gè)性化制作ASCII字符和圖案,推薦網(wǎng)址如下:
- 定制化 ASCII 字符:http://network-science.de/ascii/
- 定制化 ASCII 圖片:https://www.degraeve.com/img2txt.php
到此這篇關(guān)于教你怎么用Springboot自定義Banner圖案的文章就介紹到這了,更多相關(guān)Springboot自定義Banner圖案內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 詳解SpringBoot基礎(chǔ)之banner玩法解析
- 超個(gè)性修改SpringBoot項(xiàng)目的啟動(dòng)banner的方法
- Springboot居然可以設(shè)置動(dòng)態(tài)的Banner(推薦)
- SpringBoot之自定義Banner詳解
- SpringBoot詳解Banner的使用
- SpringBoot中的自定義Banner詳細(xì)解析
- SpringBoot的自定義banner使用方法
- SpringBoot之自定義banner使用代碼實(shí)例
- SpringBoot自定義Banner使用詳解
- SpringBoot打印Banner的實(shí)現(xiàn)示例
相關(guān)文章
徹底搞懂java并發(fā)ThreadPoolExecutor使用
這篇文章主要為大家介紹了徹底搞懂java并發(fā)ThreadPoolExecutor使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請(qǐng)通知流程
這篇文章主要介紹了 SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請(qǐng)通知流程,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下2017-12-12
spring security與corsFilter沖突的解決方案
這篇文章主要介紹了spring security與corsFilter沖突的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
rocketmq消費(fèi)負(fù)載均衡--push消費(fèi)詳解
這篇文章主要介紹了rocketmq消費(fèi)負(fù)載均衡--push消費(fèi)詳解,本文介紹了DefaultMQPushConsumerImpl消費(fèi)者,客戶端負(fù)載均衡相關(guān)知識(shí)點(diǎn)。,需要的朋友可以參考下2019-06-06
Java中synchronized?的4個(gè)優(yōu)化技巧
本文主要介紹了Java中synchronized的4個(gè)優(yōu)化技巧,synchronized在JDK?1.5?時(shí)性能是比較低的,然而在后續(xù)的版本中經(jīng)過(guò)各種優(yōu)化迭代,它的性能也得到了前所未有的提升,下文更多相關(guān)資料需要的小伙伴可以參考一下2022-05-05

