一定要知道的SpringBoot原始碼剖析之自定義Banner
一、什麼是Banner
當我們啟動一個SpringBoot應用之後,經常會在控制檯看到如下列印
-
._________
-
/\\/___'_____(_)______\\\\
-
(()\___|'_|'_||'_\/_`|\\\\
-
\\/___)||_)|||||||(_||))))
-
'|____|.__|_||_|_||_\__,|////
-
=========|_|==============|___/=/_/_/_/
-
::SpringBoot::(v2.1.6.RELEASE)
該輸出就是Banner,看起來像是一個專案的標誌一樣。
二、如何自定義Banner
如果想讓自己專案的banner列印自己想要的圖案:例如公司LOGO等,應該要怎麼辦呢?
很簡單,只需要在SpringBoot工程的/src/main/resources目錄下建立一個名為banner.txt的檔案即可,這樣,容器在啟動時就會將此檔案中的文字列印在控制檯啦。
那麼怎麼來繪製一些圖案呢?現在有很多現成的網站支援設計banner,可以參考
1.http://patorjk.com/software/taag
輸入文字進行轉化
2.http://www.network-science.de/ascii/
輸入文字進行轉化
3.http://www.degraeve.com/img2txt.php
可以將一個圖片轉為文字格式圖畫
image
三、原始碼剖析
那麼SpringBoot是如何實現的呢?
在SpringApplication的run方法中,有一行Banner printedBanner = printBanner(environment);在該方法中進行banner的獲取和列印。
SpringApplication.printBanner
-
privateBannerprintBanner(ConfigurableEnvironmentenvironment){
-
檢查列印Banner的開關是否啟
-
if(this.bannerMode==Banner.Mode.OFF){
-
returnnull;
-
}
-
ResourceLoaderresourceLoader=(this.resourceLoader!=null)?this.resourceLoader
-
:newDefaultResourceLoader(getClassLoader());
-
//準備printer
-
SpringApplicationBannerPrinterbannerPrinter=newSpringApplicationBannerPrinter(resourceLoader,this.banner);
-
//列印在日誌中
-
if(this.bannerMode==Mode.LOG){
-
returnbannerPrinter.print(environment,this.mainApplicationClass,logger);
-
}
-
//列印在控制檯
-
returnbannerPrinter.print(environment,this.mainApplicationClass,System.out);
-
}
Banner.Mode有三種:
-
OFF 不進行任何形式的Banner輸出
-
CONSOLE 在控制檯進行Banner的列印
-
LOG 列印Banner到日誌檔案中
SpringApplication中預設Banner.Mode型別為CONSOLE。
ResourceLoader是spring提供用於獲取classpath下或者resource目錄下資源的策略介面。在拿到ResourceLoader之後將其封裝為SpringApplicationBannerPrinter。之後呼叫其print方法。
SpringApplicationBannerPrinter.print
-
publicBannerprint(Environmentenvironment,Class<?>sourceClass,PrintStreamout){
-
//獲取banner
-
Bannerbanner=getBanner(environment);
-
//列印banner
-
banner.printBanner(environment,sourceClass,out);
-
returnnewPrintedBanner(banner,sourceClass);
-
}
SpringApplicationBannerPrinter.getBanner
-
privateBannergetBanner(Environmentenvironment){
-
Bannersbanners=newBanners();
-
banners.addIfNotNull(getImageBanner(environment));
-
banners.addIfNotNull(getTextBanner(environment));
-
if(banners.hasAtLeastOneBanner()){
-
returnbanners;
-
}
-
if(this.fallbackBanner!=null){
-
returnthis.fallbackBanner;
-
}
-
returnDEFAULT_BANNER;
-
}
從getBanner程式碼中看,不僅支援txt形式的banner,也支援圖片資源banner。檢視getImageBanner(environment)方法實現,可知SpringBoot將從spring.banner.image.location屬性中獲取圖片路徑,支援gif,jpg,png,然後封裝為ImageBanerr。其中Banners實質是維護了一個banner列表。在真正列印的時候進行遍歷列印。
SpringApplicationBannerPrinter.printBanner
-
publicvoidprintBanner(Environmentenvironment,Class<?>sourceClass,PrintStreamout){
-
for(Bannerbanner:this.banners){
-
banner.printBanner(environment,sourceClass,out);
-
}
-
}
所有springboot同時也支援多個banner的列印。
四、原始碼總結
從原始碼中我們可以知道更多有關banner的支援,下面將列述
-
預設自定義banner,只需要在resource目錄下放置一個banner.txt檔案即可,如果不想命名為banner.txt,則可以指定屬性spring.banner.location為自定義檔名即可
-
支援圖片資源banner。指定屬性spring.banner.image.location為圖片資源路徑
-
SpringBoot支援同時配置txt形式和圖片形式banner,並同時列印。