我是陳皮,一個在互聯網 Coding 的 ITer,微信搜索「陳皮的JavaLib」第一時間閱讀最新文章,回復【資料】,即可獲得我精心整理的技術資料,電子書籍,一線大廠面試資料和優秀簡歷模板,
文章目錄
- 前言
- 實作原理
- 默認 Banner 實作類
- ImageBanner
- ResourceBanner
- SpringBootBanner
- 實作 Banner 類
- Banner 樣式控制
- Banner 模式
- 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 這三個實作類,
- 專案啟動時,會判斷是否某些條件成立(專案中是否存在 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286216.html
標籤:其他
下一篇:[MCTF] 2021校賽題解
