0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Banner的輸出打印過程

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-13 11:25 ? 次閱讀

今天,我給大家來講講如何讓你的 Spring Boot 屌炸天,自定義 banner 。有些新入門的朋友可能會(huì)不知道 banner 是什么?它在哪里?我在哪里見過它嗎?這3連門是不是很有意思。我們今天所說的 banner 如下圖所示,想必大家在啟動(dòng) Spring Boot 項(xiàng)目的時(shí)候,大家都見過吧。

圖片

大家可能都見過永不宕機(jī)的佛祖的 banner 圖片吧。下圖,大家應(yīng)該都很熟悉吧。

圖片

今天我就來帶大家來看看源碼,看看這個(gè) banner 到底是怎么實(shí)現(xiàn)的。

Spring Boot 內(nèi)置 3 種 Banner打印方式

從下圖可以看出,Spring Boot 支持打印的Banner 方式有3種, SpringBootBanner 是Spring Boot 默認(rèn)的 Banner 打印方式, ResouceBanner 是文本類型的 Banner 打印方式, ImageBanner 是圖片類型的 Banner 打印方式。

圖片

我們來看看 Banner 接口,從下方的代碼,我們可以了解到,Banner 接口包含一個(gè) printBanner 的方法 和 Mode 的枚舉,Mode 包含三種狀態(tài),其中 OFF 表示不打印 Banner , LOG 表示把 Banner 輸出到日志文件中, CONSOLE 表示輸出到控制臺(tái),也是我們比較常見的方式。

@FunctionalInterface
public interface Banner {
    void printBanner(Environment environment, Class< ? > sourceClass, PrintStream out);
    enum Mode {
        OFF,
        CONSOLE,
        LOG
    }
}

Banner 打印流程

從 SpringApplication 類的 run 方法可以看出,printBanner 方法在 prepareEnvironment 之后,這是因?yàn)?application.properties 中有一些關(guān)于 Banner 的配置項(xiàng)。需要先解析 application.properties 的值,并將其綁定到對(duì)應(yīng)的 bean 之后,再進(jìn)行后續(xù)的操作。

public ConfigurableApplicationContext run(String... args) {
    ...
    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
    configureIgnoreBeanInfo(environment);
    // 打印 Banner
    Banner printedBanner = printBanner(environment);
    ...
}
private Banner printBanner(ConfigurableEnvironment environment) {
    if (this.bannerMode == Banner.Mode.OFF) {
        return null;
    }
    ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader
        : new DefaultResourceLoader(null);
    SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);
    if (this.bannerMode == Mode.LOG) {
        return bannerPrinter.print(environment, this.mainApplicationClass, logger);
    }
    return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}

printBanner 具體的流程如下:

  1. 判斷 bannerMode,如果是 OFF,表示不打印。如果是 LOG,表示打印到文件,否則打印到控制臺(tái)。
  2. SpringApplicationBannerPrinter 依據(jù)指定位置是是否存在文件,判斷 Banner 類型是文本還是圖片,文本類型使用 ResourceBanner, 圖片類型使用 ImageBanner, 如果都不是,使用 Spring Boot 默認(rèn)的 SpringBootBanner。
  3. SpringApplicationBannerPrinter#print 方法調(diào)用 Banner 對(duì)象的的 printBanner 方法。不同類型的 Banner 的 printBanner 方法實(shí)現(xiàn)不同。

如下是 Banner 對(duì)象的獲得方法,可以看出,Spring Boot 首先獲得 ImageBanner,然后是 ResourceBanner,需要注意的是,這兩者可以同時(shí)存在,此時(shí)會(huì)一次性打印兩種 Banner。如果都不滿足,還會(huì)去獲得 fallbackBanner,這個(gè)是用戶自己設(shè)定的 Banner,但是我們基本很少使用,大部分情況我們使用了 Spring Boot 內(nèi)置的 SpringBootBanner。

class SpringApplicationBannerPrinter {
    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;
        }
        return DEFAULT_BANNER;
    }
    private Banner getTextBanner(Environment environment) {
        String location = environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION);
        Resource resource = this.resourceLoader.getResource(location);
        try {
            if (resource.exists() && !resource.getURL().toExternalForm().contains("liquibase-core")) {
                return new ResourceBanner(resource);
            }
        }
        catch (IOException ex) {
            // Ignore
        }
        return null;
    }
    private Banner getImageBanner(Environment environment) {
        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;
        }
        for (String ext : IMAGE_EXTENSION) {
            Resource resource = this.resourceLoader.getResource("banner." + ext);
            if (resource.exists()) {
                return new ImageBanner(resource);
            }
        }
        return null;
    }
}

如何關(guān)閉 Spring Boot 的 Banner

從 SpringApplication#printBanner 方法可以看出。當(dāng)我們將 bannerMode 設(shè)置為 Banner.Mode.OFF 的時(shí)候,該方法返回 null,也就是此時(shí)不會(huì)打印 Banner。所以只要設(shè)置 bannerMode 為 OFF ,我們就能關(guān)閉 Banner 功能。

private Banner printBanner(ConfigurableEnvironment environment) {
  if (this.bannerMode == Banner.Mode.OFF) {
    return null;
  }
  ...
}

第一種就是在啟動(dòng)代碼中設(shè)置。如下所示。

public static void main(String[] args) {
        SpringApplication app
                = new SpringApplication(HelloApplication.class);
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
}

第二種是在 application.properties 中配置 spring.main.banner-mode

spring.main.banner-mode=off

這兩種方式都可以關(guān)閉 Banner,那當(dāng)它們同時(shí)存在的時(shí)候,哪個(gè)生效呢?我們可以這樣分析,啟動(dòng)代碼中調(diào)用 setBannerMode 方法,改變了 bannerMode 的值,之后 SpringApplication 對(duì)象執(zhí)行 run 方法,在 run 方法中會(huì)解析 application.properties 的值,并將其綁定到對(duì)應(yīng)的 bean,后者覆蓋前者,所以 application.properties 中的配置優(yōu)先級(jí)更高。

自定義文本類型的 Banner

Spring Boot 中自定義文本類型的 Banner 很簡單,我們只要在 resources 下增加一個(gè) banner.txt 就可以了。比如我想讓 Banner 顯示 永不宕機(jī)的佛祖雕像。那我就可以在 banner.txt 中增加以下文本。

////////////////////////////////////////////////////////////////////  
//                          _ooOoo_                               //  
//                         o8888888o                              //  
//                         88" . "88                              //  
//                         (| ^_^ |)                              //  
//                         O  =  /O                              //  
//                      ____/`---'____                           //  
//                    .'  |     |//  `.                         //  
//                   /  |||  :  |||//                          //  
//                  /  _||||| -:- |||||-                         //  
//                  |   |   -  /// |   |                       //  
//                  | _|  ''---/''  |   |                       //  
//                    .-__  `-`  ___/-. /                       //  
//                ___`. .'  /--.--  `. . ___                     //  
//              ."" '<  `.____<| >_/___.'  >'"".                  //  
//            | | :  `- `.;` _ /`;.`/ - ` : | |                 //  
//               `-.   _ __ /__ _/   .-` /  /                 //  
//      ========`-.____`-.________/___.-`____.-'========         //  
//                           `=---='                              //  
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //  
//            佛祖保佑       永不宕機(jī)      永無BUG                  //
////////////////////////////////////////////////////////////////////

打印結(jié)果是這樣的

圖片

如果我們想打印彩色的 banner 出來呢?在Spring Boot 中我們可以利用 AnsiColor 類來實(shí)現(xiàn),我們可以在 banner.txt 中使用 AnsiColor 指定后續(xù)的文本的顏色。

${AnsiColor.YELLOW}
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O  =  /O                              //
//                      ____/`---'____                           //
//                    .'  |     |//  `.                         //
//                   /  |||  :  |||//                          //
//                  /  _||||| -:- |||||-                         //
//                  |   |   -  /// |   |                       //
//                  | _|  ''---/''  |   |                       //
//                    .-__  `-`  ___/-. /                       //
//                ___`. .'  /--.--  `. . ___                     //
//              ."" '<  `.____<| >_/___.'  >'"".                  //
//            | | :  `- `.;` _ /`;.`/ - ` : | |                 //
//               `-.   _ __ /__ _/   .-` /  /                 //
//      ========`-.____`-.________/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//            佛祖保佑       永不宕機(jī)      永無BUG                    //
////////////////////////////////////////////////////////////////////

如下是最終的結(jié)果

圖片

public class ResourceBanner implements Banner {
    @Override
    public void printBanner(Environment environment, Class< ? > sourceClass, PrintStream out) {
        try {
            String banner = StreamUtils.copyToString(this.resource.getInputStream(),
                    environment.getProperty("spring.banner.charset", Charset.class, StandardCharsets.UTF_8));
            for (PropertyResolver resolver : getPropertyResolvers(environment, sourceClass)) {
                banner = resolver.resolvePlaceholders(banner);
            }
            out.println(banner);
        }
        catch (Exception ex) {
            logger.warn(LogMessage.format("Banner not printable: %s (%s: '%s')", this.resource, ex.getClass(),
                    ex.getMessage()), ex);
        }
    }
    protected List< PropertyResolver > getPropertyResolvers(Environment environment, Class< ? > sourceClass) {
        List< PropertyResolver > resolvers = new ArrayList<  >();
        resolvers.add(environment);
        resolvers.add(getVersionResolver(sourceClass));
        resolvers.add(getAnsiResolver());
        resolvers.add(getTitleResolver(sourceClass));
        return resolvers;
    }
}

我們通過上述代碼來看看,Spring Boot 為什么能打印出帶顏色的 banner, ResourceBanner 將讀取到的文本流轉(zhuǎn)換為一串字符串。再通過4個(gè)解析器,來處理待輸出的 Banner 內(nèi)容。

四個(gè)解析器分別是:

  • environment 對(duì)應(yīng) application.properties 中的配置;
  • VersionResolver 解析 spring boot 版本,
  • AnsiResolver 解析顏色或字體等樣式配置,
  • TitleResolver 解析當(dāng)前應(yīng)用的版本,名稱等。

Banner圖在線生成

在線生成 banner 的地址:

  • https://www.bootschool.net/ascii
  • http://www.network-science.de/ascii/
  • http://patorjk.com/software/taag//
  • http://www.degraeve.com/img2txt.php

總結(jié)

本文主要講述了Banner的輸出打印過程,如何打印個(gè)性化的文本 Banner。ImageBanner 沒在本文詳細(xì)說明,有興趣的朋友可以查看閱讀源碼,也比較簡單,也有助于你了解 Java 如何實(shí)現(xiàn)圖片轉(zhuǎn)文本的知識(shí)點(diǎn)。通過本文的知識(shí)點(diǎn),你也可以根據(jù)自己的要求來實(shí)現(xiàn) Banner, 設(shè)置為 fallbackBanner, 從而達(dá)到完全個(gè)性化的自定義 Banner 的效果。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8360

    瀏覽量

    150520
  • 打印
    +關(guān)注

    關(guān)注

    1

    文章

    64

    瀏覽量

    18680
  • Banner
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    7484
  • 日志
    +關(guān)注

    關(guān)注

    0

    文章

    132

    瀏覽量

    10616
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    福祿克紅外熱像儀:如何控制3D打印工藝

    3D打印過程中,由于速度、距離、材料等特性的不同,在粉末逐層堆疊累積的過程中,溫度會(huì)出現(xiàn)異常,如跳變、過高、過低、不均勻等,造成打印后的結(jié)構(gòu)件性能下降,韌度差、彈性不夠、變脆、隱紋等。使用大師之選系列熱像儀在可以為金屬
    發(fā)表于 05-08 07:21

    AB32VG1開發(fā)板開發(fā)環(huán)境搭建和串口調(diào)試打印過程

    有幸申請(qǐng)到開發(fā)板,下面說下開發(fā)環(huán)境搭建和串口調(diào)試打印過程1:先下載RTT studio開發(fā)工具,RTT studio下載地址2:下載完成后,需要測(cè)試帳號(hào)才可以登錄IDE,這部分略過3:新建RTT工程
    發(fā)表于 10-10 17:29

    東芝數(shù)碼復(fù)印機(jī)復(fù)印過程概述

    東芝數(shù)碼復(fù)印機(jī)復(fù)印過程概述: 充電: 將負(fù)電荷充至感光鼓的表面。 原稿曝光: 利用光照射原稿,將原稿上的圖像轉(zhuǎn)換為
    發(fā)表于 01-18 11:32 ?903次閱讀

    東芝數(shù)碼復(fù)印機(jī)復(fù)印過程詳述

    東芝數(shù)碼復(fù)印機(jī)復(fù)印過程詳述 1 、感光鼓 感光鼓包括兩層。外層是由有機(jī)光敏導(dǎo)體( OPC )制造的光敏層,內(nèi)
    發(fā)表于 01-18 11:35 ?981次閱讀

    東芝數(shù)碼復(fù)印機(jī)原理與復(fù)印過程概述

    東芝數(shù)碼復(fù)印機(jī)原理與復(fù)印過程概述 復(fù)印過程概述: 充電: 將負(fù)電荷充至感光鼓的表面。 原稿曝光: 利用光照射原稿,將
    發(fā)表于 01-18 11:44 ?2562次閱讀

    什么是Banner

    什么是Banner  英文縮寫: Banner 中文譯名: 網(wǎng)頁標(biāo)識(shí) 分  類: IP與多媒體 解  釋: 網(wǎng)頁標(biāo)識(shí)通常被用作橫
    發(fā)表于 02-22 11:13 ?1087次閱讀

    3D打印機(jī)使用說明書包括操作說明和注意事項(xiàng)和保養(yǎng)資料免費(fèi)下載

    打印過程中,請(qǐng)勿觸碰電源線、USB 數(shù)據(jù)線及拔出 SD 卡,否則打印過程會(huì)中斷。擠出機(jī)在未擠絲的情況下,請(qǐng)勿長時(shí)間加熱,避免噴嘴堵塞。在進(jìn)行打印機(jī)調(diào)試時(shí),噴頭會(huì)擠出打印材料,因此請(qǐng)保
    發(fā)表于 10-10 08:00 ?0次下載
    3D<b class='flag-5'>打印</b>機(jī)使用說明書包括操作說明和注意事項(xiàng)和保養(yǎng)資料免費(fèi)下載

    打印機(jī)如何取消打印任務(wù)

    如果文檔正在打印過程中需要取消打印任務(wù),則直接點(diǎn)擊打印任務(wù)窗口中的“暫?!卑粹o即可取消打印任務(wù)。也可能通過點(diǎn)擊Windows任務(wù)欄右下角的打印
    的頭像 發(fā)表于 04-12 16:10 ?6.8w次閱讀

    網(wǎng)印過程中網(wǎng)會(huì)出現(xiàn)哪些故障

    絲網(wǎng)印刷是孔版印刷術(shù)中的一種主要印刷方法。印版呈網(wǎng)狀,印刷時(shí)印版上的油墨在刮墨板的擠壓下從版面通孔部分漏印至承印物上。網(wǎng)版方面的故障,有制網(wǎng)版時(shí)產(chǎn)生的問題,也有網(wǎng)印過程中網(wǎng)版產(chǎn)生的問題,本文僅就網(wǎng)印過程中網(wǎng)會(huì)出現(xiàn)哪些故障。
    的頭像 發(fā)表于 05-07 14:37 ?2757次閱讀

    膠印技術(shù)工藝參數(shù)會(huì)如何影響膠印過程

    在SMT貼片加工廠中,大多數(shù)使用膠印技術(shù)的客戶在錫膏印刷技術(shù)方面往往都是非常有經(jīng)驗(yàn)的。膠印技術(shù)相關(guān)工藝參數(shù)的確定可以以錫膏印刷技術(shù)的工藝參數(shù)作為參考。下面淺談?dòng)∷⒐に噮?shù)是如何影響膠印過程的。
    的頭像 發(fā)表于 10-24 11:33 ?3310次閱讀

    3D打印過程中會(huì)遇到哪些問題

    3D打印俗稱增材制造,是一種可快速成型技術(shù)。它按照電子模型圖的指示,采用分層加工、疊加成形的方式逐層增加材料來打印目標(biāo)物體。特別是在小批量生產(chǎn)中,3D打印是一種相對(duì)快速且經(jīng)濟(jì)有效的生產(chǎn)方式零件符合
    的頭像 發(fā)表于 03-22 17:23 ?4336次閱讀

    計(jì)算機(jī)視覺算法在監(jiān)測(cè)金屬3D打印過程中產(chǎn)生的缺陷

    卡內(nèi)基梅隆大學(xué)工程學(xué)院(CMU)的兩位研究人員已經(jīng)想出了如何將3D打印和機(jī)器學(xué)習(xí)結(jié)合起來進(jìn)行實(shí)時(shí)過程監(jiān)控,這種做法可以檢測(cè)出零件在3D打印過程中的異常情況。
    的頭像 發(fā)表于 12-26 12:51 ?482次閱讀

    如何避免3D打印機(jī)使用過程中出現(xiàn)拉絲

    當(dāng)我們?cè)谑褂?d打印機(jī)打印模型時(shí),打印過程中有時(shí)會(huì)在模型上出現(xiàn)絲狀塑料,尤其是當(dāng)噴嘴從一端直接跳到另一端時(shí)。我們將3d打印過程中出現(xiàn)的這些細(xì)絲現(xiàn)象統(tǒng)稱為“拉絲”。在大多數(shù)3d
    發(fā)表于 09-10 16:33 ?3233次閱讀

    為什么在金屬 3D 打印過程中使用氧氣分析儀很重要?

    。對(duì)于航空航天、汽車和醫(yī)療等行業(yè),產(chǎn)品的質(zhì)量在金屬 3D 打印過程中不會(huì)因氧氣的存在而受損,這一點(diǎn)至關(guān)重要。
    的頭像 發(fā)表于 08-19 10:50 ?1207次閱讀
    為什么在金屬 3D <b class='flag-5'>打印過程</b>中使用氧氣分析儀很重要?

    晶振在3D打印技術(shù)中的應(yīng)用都有哪些?

    3D打印過程中,需要進(jìn)行大量的數(shù)據(jù)處理,包括模型的切片、打印路徑的規(guī)劃等。
    的頭像 發(fā)表于 03-17 11:29 ?504次閱讀