spring boot 在應用程序啟動時會打印出 banner 信息。spring 是可擴展的,banner 也是可以自由定制的,比如打印出個人的網站信息等,甚至是圖片,本文就來探討一下這個問題。
注:本文基於 spring boot 版本 1.5.12.RELEASE。
源碼分析
默認,spring boot 會打印出如下內容:
ASCII Art,顯目的單詞 spring,附帶 spring boot 版本信息。
Spring boot 是如何處理的呢?
帶着問題,我們來分析源碼,定位到 SpringApplication 類的 printBanner 方法,源碼如下:

代碼比較簡單,我們看到打印 banner 的操作委托給了 SpringApplicationBannerPrinter 類,再來看它的源碼:

上述代碼,我們稍加解釋:
-
打印 banner 前自然先要獲取 Banner 對象
-
打印 banner 的操作實際上由 Banner 本身來完成
-
打印到日志是先由 Banner 將內容輸出到內存中拿到打印內容后再委托給 logger 來打印
-
打印到標准輸出是將 System.out 作為參數傳入 Banner 對象作為輸出目的地
我們再來看看獲取 banner 這段代碼:

這段代碼大致邏輯:
-
創建一個 Banners 對象,可組合多個 banner
-
嘗試獲取基於圖片的 banner
-
嘗試獲取基於文本的 banner
-
前兩步操作完成后,如果拿到至少一個 banner 則返回 Banners 對象
-
前兩步操作后都沒有獲取到 banner,返回自定義的 banner (如果存在)
-
若自定義 banner 也不存在,返回默認的
注: Banners 也實現了 Banner 接口,運用了組合模式,實際上可同時打印圖片和文本 banner。
以上內容就是打印 banner 的大體邏輯,我們再來看一看細節。
基於配置的方式自定義 Banner
看看基於圖片和文本兩種形式的 banner 獲取源碼:
注:為了方便讀者閱讀,筆者把 spring 定義的常量替換成了原字符串本身

通過這段代碼,我們可得出結論:
基於圖片的 banner
-
可通過配置參數 banner.image.location 來指定
-
可將名為 banner.jpg (gif|png) 的文件放在 classpath 目錄
基於文件的 banner
-
可通過配置參數 banner.location 來指定
-
可將名為 banner.txt 的文件放在 classpath 目錄
居然可以打印圖片,是不是很好玩,那么我們就來試一把。
我們在 classpath 目錄下存放一個名為 banner.jpg 的圖片,圖片如下:
同時也放一個名為 banner.txt 的文件,內容為:
Hello, Spring boot
運行程序,最終我們看到如下效果:
圖片的打印效果是 ASCII 字符畫,太好玩了。ASCII 字符畫后面緊接着文本文件的內容。
至此,我相信你已經學會如何自定義一個好玩的 banner 了,但我們的文章還要繼續。剛才說的兩種方式是基於配置的形式,接下來我們來說一下如何基於編程的方式來實現。
基於編程的方式自定義 Banner
既然要通過編程的方式實現,那自然要實現 Banner 接口了,源碼如下:

代碼也很簡單, 只定義了一個 printBanner 方法。
同時還定義了打印模式:
-
禁用(不打印)
-
控制台(標准輸出)
-
日志
前面有提到 Banners ,我們也看一下源碼:

Banners 也實現了 Banner 接口,內置一個 Banner 集合,運用了組合模式。
還記得前面提到的 spring 默認 Banner 么,我們來看一下源碼:

是不是很好玩,內置了 ASCII 字符畫。
既然我們要編寫自己的 Banner,那么很簡單,照葫蘆畫瓢。
看一下筆者的簡單實現:

Banner 實現好了,我們怎么使它生效呢。很簡單,我們看一下啟動類:

我們再看一下打印效果,如下圖:
看到這里,你是不是很想自己實現一個有趣的 banner 呢?
小結
本文中我們主要講了如何自定義 Banner,我們既可以通過配置的方式來指定 banner 文件又可通過編程的方式來實現。