怎么建網(wǎng)站鏈接效果最好的推廣軟件
文章目錄
- 一、介紹
- 二、演示環(huán)境
- 三、自定義banner
- 1. 文本
- 2. 圖片
- 3. placeholder占位符
- 4. 關(guān)閉banner
- 四、源碼分析
- 1. 關(guān)閉banner
- 2. banner模式
- 3. banner打印器
- 4. 打印banner
- ① 獲取banner
- ② 打印banner
- 5. 版本號占位符的解析器
- 6. 文本格式占位符的解析器
- 7. 應(yīng)用標(biāo)題占位符的解析器
- 五、總結(jié)
一、介紹
Banner即橫幅的意思,我們在慶祝某些事情時有些顯眼包總會是拉個橫幅以表明意圖。
在我們啟動springboot項目時,springboot往往也會打印出一個默認(rèn)的橫幅,該橫幅中包含了一些信息如springboot版本號等,如下圖所示。
既然有默認(rèn)的,當(dāng)然springboot也允許我們對banner進(jìn)行自定義設(shè)置,如將banner設(shè)置為文本、圖片,甚至關(guān)閉banner的輸出。如下所示
是否略顯炫酷?下面我們來介紹如何自定義banner,并通過源碼進(jìn)行分析。
二、演示環(huán)境
本演示項目的環(huán)境如下:
- java:1.8
- springboot:2.4.3
三、自定義banner
1. 文本
當(dāng)我們需要自定義文本banner時,只需要在類路徑classpath下新建一個文件,文件名為banner.txt
(springboot默認(rèn)),然后編輯作為banner的文本即可,如下所示。
此時輸出如下
如果不使用springboot默認(rèn)的banner文件名,則需要通過在配置文件中配置spring.banner.location
,如下所示
如果文件的編碼不是UTF-8,則可以在配置文件中通過spring.banner.charset
配置字符集,如下所示
spring:banner:location: fozuBanner.txtcharset: UTF-32
2. 圖片
除了文本banner外,springboot還允許我們自定義圖片banner。并且如果兩種banner同時存在,則先輸出圖片banner、再輸出文本banner。
默認(rèn)地,springboot將從classpath類路徑下獲取banner.gif
、banner.jpg
、banner.png
作為圖片banner。當(dāng)然也可以通過在配置文件中配置spring.banner.image.location
來指定圖片的位置。
在輸出圖片banner時,springboot將會把圖片轉(zhuǎn)化成ASCII藝術(shù)畫輸出,而非無腦式地將圖片輸出。
如下圖所示,我們在類路徑下添加圖片,并將其命名為banner.png
。
啟動項目后的輸出如下
3. placeholder占位符
springboot允許我們在banner中使用${}
格式的占位符,但僅限于文本banner。內(nèi)置的占位符有應(yīng)用版本、springboot版本、字體樣式、應(yīng)用名。下面我們一一介紹。
-
應(yīng)用版本
占位符為
${application.version}
或${application.formatted-version}
。springboot允許我們在文本banner中添加應(yīng)用版本號。通過在文本banner中添加
${application.version}
或${application.formatted-version}
時,springboot從MANIFEST.MF
中讀取Implementation-Version
的值。例如,
MANIFEST.MF
中Implementation-Version
的值為1.0.0
,則${application.version}
得到的值為1.0.0
;${application.formatted-version}
的值為v1.0.0
,多了個前綴v
。注意:該信息只有通過
Spring Boot launchers
方式啟動時才會生效。 -
springboot版本
占位符為
${spring-boot.version}
或${spring-boot.formatted-version}
。獲取當(dāng)前項目使用的springboot的版本號,同樣的,后者會給前者獲取的值添加前綴
v
。如下圖所示 -
字體樣式
占位符為
${AnsiColor.NAME}
、${AnsiBackground.NAME}
、${AnsiStyle.NAME}
。當(dāng)我們使用
${AnsiColor.RED}
時,打印的字體將變成紅色;使用${AnsiBackground.YELLOW}
時,背景顏色將變成黃色;使用${AnsiStyle.BOLD}
時,將打印粗體。如下圖所示 -
應(yīng)用名
占位符為
${application.title}
。springboot允許我們在文本banner中添加應(yīng)用名稱。通過在文本banner中添加
${application.title}
時,springboot從MANIFEST.MF
中讀取Implementation-Title
的值。例如,
MANIFEST.MF
中Implementation-Title
的值為MyApp
,則Implementation-Title
得到的值為MyApp
。注意:該信息只有通過
Spring Boot launchers
方式啟動時才會生效。
4. 關(guān)閉banner
我們介紹了文本banner、圖片banner后,接下來介紹如何關(guān)閉banner,關(guān)閉bannner后在項目啟動時便不再輸出banner。
方法當(dāng)然也很簡單,對于關(guān)閉bannner功能,springboot在SpringApplication
類中提供了響應(yīng)的方法setBannerMode()
來關(guān)閉banner。下面對我們的主啟動類進(jìn)行修改。
-
修改前
public static void main(String[] args){SpringApplication.run(BannerApplication.class, args); }
-
修改后
public static void main(String[] args){SpringApplication springApplication = new SpringApplication(BannerApplication.class);// 將bannner的模式設(shè)置為off,即關(guān)閉springApplication.setBannerMode(Banner.Mode.OFF);springApplication.run(args); }
-
啟動項目
四、源碼分析
我們知道springboot是通過SpringApplication
類中的run()
方法啟動的,在該方法中調(diào)用printBanner()
方法打印banner,如下圖所示
下面我們進(jìn)入該方法
1. 關(guān)閉banner
在printBanner()
方法中我們首先看到對bannerMode
的判斷,如果是OFF
,則直接返回null
。
if (this.bannerMode == Banner.Mode.OFF) {return null;
}
而前面我們在演示的時候提到過,springboot提供了對應(yīng)的方法。
public void setBannerMode(Banner.Mode bannerMode) {this.bannerMode = bannerMode;
}
我們看一下Banner.Mode
為何物?
2. banner模式
Banner.Mode
表示為Banner
的模式,springboot提供了三種模式:OFF關(guān)閉、CONSOLE控制臺、LOG日志文件。
springboot默認(rèn)的banner模式為CONSOLE控制臺。
3. banner打印器
在printBanner()
方法中創(chuàng)建了banner打印器實例,代碼如下所示
private Banner printBanner(ConfigurableEnvironment environment) {// ...SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);// ...
}
在調(diào)用構(gòu)造方法實例化打印器時,傳入資源加載器 和 兜底banner,兜底banner的含義為如果項目中沒有指定的文本banner或圖片banner時,則使用兜底banner,如果兜底banner依然不存在,最后才使用springboot默認(rèn)banner。
springboot提供了設(shè)置兜底banner的方法:
public void setBanner(Banner banner) {this.banner = banner;
}
與設(shè)置banner模式相同,在主啟動類中設(shè)置一個自定義的banner,該自定義banner必須實現(xiàn)Banner
接口的printBanner()
方法。
public static void main(String[] args){SpringApplication springApplication = new SpringApplication(BannerApplication.class);springApplication.setBanner(new CustomBanner());springApplication.run(args);
}
4. 打印banner
在完成banner打印器的實例化以后,就開始調(diào)用打印器的print()
方法對banner進(jìn)行打印了,且打印器提供了兩個重載的的print()
方法,分別用于日志模式和控制臺模式。這兩個重載方法的不同之處在第三個參數(shù)。如下所示
private Banner printBanner(ConfigurableEnvironment environment) {// ...if (this.bannerMode == Mode.LOG) {return bannerPrinter.print(environment, this.mainApplicationClass, logger);}return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}
這兩個重載方法的基本邏輯是相同的,即獲取banner、打印banner、返回結(jié)果。我們以控制臺模式的print()
方法為例。
Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {// 獲取bannerBanner banner = getBanner(environment);// 打印bannerbanner.printBanner(environment, sourceClass, out);// 返回結(jié)果return new PrintedBanner(banner, sourceClass);
}
① 獲取banner
我們進(jìn)入getBanner()
方法查看其實現(xiàn)
該實現(xiàn)邏輯也很清晰,就是先后獲取圖片banner添加到banners中,如果banners中存在banner,則返回;否則返回兜底banner;如果兜底banner還不存在,則返回默認(rèn)banner。
-
獲取圖片banner
獲取到的圖片banner用
ImageBanner
對象表示。 -
獲取文本banner
獲取到的文本banner用
ResourceBanner
對象表示。 -
兜底banner
前面我們在介紹banner打印器時,已經(jīng)詳細(xì)介紹過了。
-
默認(rèn)banner
默認(rèn)banner使用常量
DEFAULT_BANNER
表示為SpringBootBanner
對象。如下所示進(jìn)入
SpringBootBanner
后發(fā)現(xiàn)發(fā)現(xiàn)我們再熟悉不過的默認(rèn)banner,原來藏在這里。
② 打印banner
前面在getBanner()
方法中獲取到的banner集合被添加到Bannners
中,注意一下,類Banners
是Banner
的子類,在它實現(xiàn)的printBanner()
方法中,通過遍歷內(nèi)部的banner集合并調(diào)用printBanner()
方法對不同的banner進(jìn)行打印。
下面我們對不同類型bannner的打印邏輯進(jìn)行分析
-
圖片banner
圖片banner被封裝在
ImageBanner
對象中,在打印圖片banner時,會對java.awt.headless
的配置進(jìn)行處理,然后再調(diào)用其重載方法真正地輸出圖片banner。下面我們點擊重載
printBanner()
方法,查看其真正輸出圖片banner的邏輯。在該方法中,從配置中獲取圖片banner的寬高等基本樣式,然后將其輸出,在輸出過程中將圖片轉(zhuǎn)為ASCII藝術(shù)圖。
-
文本banner
文本banner被封裝在
ResourceBanner
對象中,我們進(jìn)入該類的printBanner()
方法。該方法邏輯為將文本banner按照配置文件中
spring.banner.charset
指定的字符集轉(zhuǎn)換為對應(yīng)的banner字符串;然后獲取用于解析${}
形式的占位符的解析器集合,利用解析器處理banner字符串中的占位符。最后將處理后的banner字符串輸出。下面我們看一下有哪些占位符解析器
從源碼中,我們看到,有處理版本號的解析器、文本格式的解析器、應(yīng)用標(biāo)題的解析器。
5. 版本號占位符的解析器
獲取版本號占位符的解析器是通過getVersionResolver()
方法完成的,如下圖所示,可以看到springboot內(nèi)置給我們獲取應(yīng)用版本號和springboot版本號的占位符。
6. 文本格式占位符的解析器
獲取文本格式占位符的解析器是通過getAnsiResolver()
方法完成的。如下圖所示,可以看到內(nèi)置了多種設(shè)置文本格式的方式。
下面我們以設(shè)置文本格式和文本顏色為例
-
文本格式
文本格式通過
AnsiStyle
設(shè)置,所以我們點擊其對應(yīng)的AnsiStyle
類,發(fā)現(xiàn)我們可以設(shè)置的文本格式如下 -
文本顏色
文本顏色通過
AnsiColor
設(shè)置,所以我們點擊其對應(yīng)的AnsiColor
類,發(fā)現(xiàn)我們可以設(shè)置的文本顏色如下
7. 應(yīng)用標(biāo)題占位符的解析器
獲取應(yīng)用標(biāo)題占位符的解析器是通過getTitleResolver()
方法完成的。如下圖所示。
五、總結(jié)
- 優(yōu)先級:圖片、文本banner > 兜底banner > 默認(rèn)bannner
- 文本banner可以添加內(nèi)置的占位符如版本號、文本顏色、文本格式等。
- 圖片banner的打印是將圖片轉(zhuǎn)為ASCII藝術(shù)圖后打印的。
紙上得來終覺淺,絕知此事要躬行。
————————————————我是萬萬歲,我們下期再見————————————————