一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

Banner的輸出打印過(guò)程

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-13 11:25 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

圖片

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

圖片

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

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

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

圖片

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

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

Banner 打印流程

從 SpringApplication 類(lèi)的 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 類(lèi)型是文本還是圖片,文本類(lèi)型使用 ResourceBanner, 圖片類(lèi)型使用 ImageBanner, 如果都不是,使用 Spring Boot 默認(rèn)的 SpringBootBanner。
  3. SpringApplicationBannerPrinter#print 方法調(diào)用 Banner 對(duì)象的的 printBanner 方法。不同類(lèi)型的 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í)更高。

自定義文本類(lèi)型的 Banner

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

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

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

圖片

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

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

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

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

  • environment 對(duì)應(yīng) application.properties 中的配置;
  • VersionResolver 解析 spring boot 版本,
  • AnsiResolver 解析顏色或字體等樣式配置,
  • TitleResolver 解析當(dāng)前應(yīng)用的版本,名稱(chē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的輸出打印過(guò)程,如何打印個(gè)性化的文本 Banner。ImageBanner 沒(méi)在本文詳細(xì)說(shuō)明,有興趣的朋友可以查看閱讀源碼,也比較簡(jiǎn)單,也有助于你了解 Java 如何實(shí)現(xiàn)圖片轉(zhuǎn)文本的知識(shí)點(diǎn)。通過(guò)本文的知識(shí)點(diǎn),你也可以根據(jù)自己的要求來(lái)實(shí)現(xiàn) Banner, 設(shè)置為 fallbackBanner, 從而達(dá)到完全個(gè)性化的自定義 Banner 的效果。

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

    關(guān)注

    33

    文章

    9000

    瀏覽量

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

    關(guān)注

    1

    文章

    66

    瀏覽量

    19014
  • Banner
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

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

    關(guān)注

    0

    文章

    144

    瀏覽量

    10865
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

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

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

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

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

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

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

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

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

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

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

    什么是Banner

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

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

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

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

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

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

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

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

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

    3D打印過(guò)程中會(huì)遇到哪些問(wèn)題

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

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

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

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

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

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

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

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

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