1. 程式人生 > 實用技巧 >一定要知道的SpringBoot原始碼剖析之自定義Banner

一定要知道的SpringBoot原始碼剖析之自定義Banner

一、什麼是Banner

當我們啟動一個SpringBoot應用之後,經常會在控制檯看到如下列印

  1. ._________

  2. /\\/___'_____(_)______\\\\

  3. (()\___|'_|'_||'_\/_`|\\\\

  4. \\/___)||_)|||||||(_||))))

  5. '|____|.__|_||_|_||_\__,|////

  6. =========|_|==============|___/=/_/_/_/

  7. ::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

image

三、原始碼剖析

那麼SpringBoot是如何實現的呢?

在SpringApplication的run方法中,有一行Banner printedBanner = printBanner(environment);在該方法中進行banner的獲取和列印。

SpringApplication.printBanner

  1. privateBannerprintBanner(ConfigurableEnvironmentenvironment){

  2. 檢查列印Banner的開關是否啟

  3. if(this.bannerMode==Banner.Mode.OFF){

  4. returnnull;

  5. }

  6. ResourceLoaderresourceLoader=(this.resourceLoader!=null)?this.resourceLoader

  7. :newDefaultResourceLoader(getClassLoader());

  8. //準備printer

  9. SpringApplicationBannerPrinterbannerPrinter=newSpringApplicationBannerPrinter(resourceLoader,this.banner);

  10. //列印在日誌中

  11. if(this.bannerMode==Mode.LOG){

  12. returnbannerPrinter.print(environment,this.mainApplicationClass,logger);

  13. }

  14. //列印在控制檯

  15. returnbannerPrinter.print(environment,this.mainApplicationClass,System.out);

  16. }

Banner.Mode有三種:

  • OFF 不進行任何形式的Banner輸出

  • CONSOLE 在控制檯進行Banner的列印

  • LOG 列印Banner到日誌檔案中

SpringApplication中預設Banner.Mode型別為CONSOLE。

ResourceLoader是spring提供用於獲取classpath下或者resource目錄下資源的策略介面。在拿到ResourceLoader之後將其封裝為SpringApplicationBannerPrinter。之後呼叫其print方法。

SpringApplicationBannerPrinter.print

  1. publicBannerprint(Environmentenvironment,Class<?>sourceClass,PrintStreamout){

  2. //獲取banner

  3. Bannerbanner=getBanner(environment);

  4. //列印banner

  5. banner.printBanner(environment,sourceClass,out);

  6. returnnewPrintedBanner(banner,sourceClass);

  7. }

SpringApplicationBannerPrinter.getBanner

  1. privateBannergetBanner(Environmentenvironment){

  2. Bannersbanners=newBanners();

  3. banners.addIfNotNull(getImageBanner(environment));

  4. banners.addIfNotNull(getTextBanner(environment));

  5. if(banners.hasAtLeastOneBanner()){

  6. returnbanners;

  7. }

  8. if(this.fallbackBanner!=null){

  9. returnthis.fallbackBanner;

  10. }

  11. returnDEFAULT_BANNER;

  12. }

從getBanner程式碼中看,不僅支援txt形式的banner,也支援圖片資源banner。檢視getImageBanner(environment)方法實現,可知SpringBoot將從spring.banner.image.location屬性中獲取圖片路徑,支援gif,jpg,png,然後封裝為ImageBanerr。其中Banners實質是維護了一個banner列表。在真正列印的時候進行遍歷列印。

SpringApplicationBannerPrinter.printBanner

  1. publicvoidprintBanner(Environmentenvironment,Class<?>sourceClass,PrintStreamout){

  2. for(Bannerbanner:this.banners){

  3. banner.printBanner(environment,sourceClass,out);

  4. }

  5. }

所有springboot同時也支援多個banner的列印。

四、原始碼總結

從原始碼中我們可以知道更多有關banner的支援,下面將列述

  • 預設自定義banner,只需要在resource目錄下放置一個banner.txt檔案即可,如果不想命名為banner.txt,則可以指定屬性spring.banner.location為自定義檔名即可

  • 支援圖片資源banner。指定屬性spring.banner.image.location為圖片資源路徑

  • SpringBoot支援同時配置txt形式和圖片形式banner,並同時列印。