日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747


 

前言

每次啟動SpringBoot項目時,總是能看到控制臺打印了一串字符,隱約能辨認出是“Spring”,不知大家是否也好奇過是怎么實現的,是直接打印固定的字符串,還是根據什么算法去生成的?于是閑暇無事,探究一番。


 

 

只想修改banner可以跳到文末查看
SpringBoot是怎么打印的 Banner默認實現類 SpringBootBanner

 

1、根據控制臺打印的字符進行全局搜索,筆者選取:: Spring Boot ::進行搜索,定位到了org.springframework.boot.SpringBootBanner。

 

IDEA全局搜索:CTRL + SHIFT + R

 


 

2、進入SpringBootBanner類,先看下注釋Default Banner implementation which writes the 'Spring' banner.,說了兩個信息:1、當前類是SpringBoot Banner的默認實現;2、打印的字符是“Spring”。

3、往下看,SpringBootBanner實現了Banner接口。Banner包括printBanner方法和枚舉Mode。
根據Mode中的注釋和枚舉值可以看出,Banner有三種狀態:關閉、打印到控制臺、打印到日志。具體使用場景留待后續分析。

Banner源碼

4、往下看到類的屬性BANNER和SPRING_BOOT,也能辨認出是控制臺打印的那些字符。

類里面只有一個方法printBanner,負責打印Banner字符。邏輯比較清晰,第一部分逐行打印BANNER形成圖案;第二部分打印SpringBoot版本號,總長度由STRAP_LINE_SIZE控制。

SpringBootBanner完整代碼 Banner核心控制類 SpringApplicationBannerPrinter

1、上節找到了負責存儲和打印Banner字符的類SpringBootBanner,現在向調用鏈上方繼續尋找,通過CTRL + B或者全局搜索可以發現SpringBootBanner在SpringApplicationBannerPrinter類中作為類變量,大概能猜測出這個SpringApplicationBannerPrinter類是Banner打印的核心控制器。

2、進入SpringApplicationBannerPrinter類,照例先看注釋Class used by SpringApplication to print the application banner.,意思是當前類被SpringApplication用來打印banner。

這個SpringApplication好像有點眼熟,名字和我們SpringBoot項目的啟動類有點相似,翻翻啟動類的代碼,想起我們就是通過SpringApplication的run方法啟動項目,banner打印調用也是由SpringApplication控制的,后續會詳細分析。(占坑,后續SpringBoot啟動流程也會出一篇博客去探討一下)


 

回歸正題,繼續從類的屬性開始看,根據名字猜測大概含義,留待后續驗證:

 

  1. BANNER_LOCATION_PROPERTY:Spring配置,大概是banner文件的路徑。
  2. BANNER_IMAGE_LOCATION_PROPERTY:Spring配置,banner圖片的路徑(存疑,控制臺難道能打印圖片?)。
  3. DEFAULT_BANNER_LOCATION = "banner.txt":取值是txt文件,猜測是banner文件的默認位置。
  4. String[] IMAGE_EXTENSION = { "gif", "jpg", "png" }:取值是常見圖片的后綴,結合第二個屬性猜測是用來對banner圖片類型做限制。
  5. DEFAULT_BANNER = new SpringBootBanner():把上節分析的SpringBootBanner當做Banner默認實現類
  6. ResourceLoader resourceLoader:ResourceLoader簡單來說是Spring加載資源的統一抽象,由實現類提供具體邏輯。
    在Spring中讀取xml配置文件加載應用上下文的ClassPathXmlApplicationContext,就是ResourceLoader的子類。
  7. Banner fallbackBanner:翻譯過來是回退banner,暫時猜不出作用,等待后續填坑。

     

     

 

3、往下看方法,只有兩個非私有方法,都是print的重載方法,差別在于第三個參數,分別是Log logger和PrintStream out,代表這兩個方法分別負責日志打印和控制臺打印。

緊扣主題,先看負責控制臺打印的方法。

Banner print(Environment environment, Class sourceClass, PrintStream out) { Banner banner = getBanner(environment); banner.printBanner(environment, sourceClass, out); return new PrintedBanner(banner, sourceClass); }

代碼很精簡,第一行獲取Banner類,第二行調用Banner的print方法打印banner圖案,最后生成PrintedBanner并返回。

1. getBanner

getBanner源碼

查看getBanner方法,首先創建Banners,底層就是Banner數組,由于存在控制臺、日志兩種打印方式,使用此類方便批量處理。

Banners源碼

接著就是調用getImageBanner和getTextBanner方法獲取Banner,如果Banner數組不為空則返回,否則檢查fallbackBanner。

這個fallbackBanner光看名字看不出是什么,使用CTRL+B查看引用,發現是在SpringApplication#printBanner里注入進來的,如下圖。


 

繼續查找this.banner會發現,最終Banner只能通過SpringApplicationBuilder#banner注入。


 

SpringApplicationBuilder是通過Constructor(構造器)模式實現的SpringApplication構造器。
查看banner方法的注釋,我們可以知道這里注入的Banner實例會在沒有靜態banner文件時使用
回過頭來,fallbackBanner的坑填上了,它是在SpringApplicationBannerPrinter找不到txt文件或者圖片作為banner素材的時候使用。

如果fallbackBanner也為空,則最終返回兜底方案-SpringBootBanner。

getBanner的結構分析完了,實際情況我們知道走的是兜底方案,也就是只要我們能讓getImageBanner、getTextBanner或者fallbackBanner不為空,就能改變banner打印的圖案。
帶著這個想法,我們就去看看getImageBanner和getTextBanner是咋回事。

2、getImageBanner
查看源碼,首先environment.getProperty讀取配置spring.banner.image.location獲取圖片位置。

配置文件讀取若為空則遍歷圖片后綴數組IMAGE_EXTENSION,采用"banner." + ext拼接方式得到圖片相對路徑,并嘗試加載。加載成功后會生成ImageBanner并返回。

接收圖片資源并處理打印的邏輯都封裝在ImageBanner中,后續單獨寫一篇文章嘗試分析圖片打印邏輯。

按照我們的分析,只要在配置文件中添加spring.banner.image.location并賦值正確的圖片路徑,或者在resources目錄下存放一張名字為“banner”、后綴是gif,jpg, png其中之一的圖片,SpringApplicationBannerPrinter就會打印出來。
注: 為什么沒加前綴classpath:也可以放在resources目錄下,可以查看DefaultResourceLoader#getResource對于banner.jpg這種location的處理邏輯。

后續章節會有打印效果。

getImageBanner源碼

3、getTextBanner
查看源碼,同樣是先從配置文件中讀取banner文件的location并嘗試加載資源,和getImageBanner不同的是,這里讀取不到會使用默認值banner.txt。

加載資源后有一個Resource的限制條件!resource.getURL().toExternalForm().contains("liquibase-core"),這里不明白這個條件的含義,只查詢到了Liquibase是一個用于跟蹤、管理和應用數據庫變化的開源工具。

資源校驗通過后生成ResourceBanner并返回。

getTextBanner源碼

接下來進入ResourceBanner看下打印細節。
printBanner結構比較簡單,第一部分設置banner字符集,優先讀取配置spring.banner.charset,無配置則默認設置為UTF-8。
第二部分去解析banner字符,比如將${xxx}占位符解析成實際的值。
第三部分就是調用流打印輸出。

ResourceBanner#printBanner banner打印調用方-SpringApplication

上節看完SpringApplicationBannerPrinter,這節來尋找打印banner的調用方。

CTRL+B查看SpringApplicationBannerPrinter#print的引用,定位到了SpringApplication#printBanner。源碼如下。

從整體結構來看,printBanner方法根據this.bannerMode取值不同,執行不同的打印策略:不打印、打印到日志、打印到控制臺。

 

那么這個bannerMode是怎么設置的?查看初始化的代碼,默認值是CONSOLE。 繼續尋找,最終定位到了SpringApplicationBuilder#bannerMode,意味著bannerMode只能通過構造器進行注入。

 

繼續尋找printBanner的調用方,定位到了SpringApplication#run(String...)。

上面有提到過,通常我們SpringBoot項目都是去調用SpringApplication#run(Class, String...)去啟動項目,底層是通過new關鍵字創建SpringApplication對象,最后調用SpringApplication#run(String...)完成一系列的資源初始化。

所以這就可以解釋大多數情況下,我們的SpringBoot項目啟動時都會打印那個默認的“Spring”字符。

SpringApplication#printBanner源碼

如何修改項目啟動的banner 修改banner打印策略

經上分析,banner打印策略包括控制臺日志不打印

1. 隱式
默認策略是控制臺,只需大多數情況一樣,項目啟動類通過SpringApplication.run(DistinctAppUserServiceApplication.class, args);啟動,無需指定。

2. 顯式注入
通過SpringApplicationBuilder構造器顯式注入banner打印策略。

@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { new SpringApplicationBuilder(DemoApplication.class) // Banner.Mode.LOG 打印到日志 // Banner.Mode.OFF 不打印 .bannerMode(Banner.Mode.CONSOLE) .run(args); }}

打印效果
打印到控制臺


 

打印到日志:INFO級別


 

修改banner內容 文本

方式一:在src/main/resources下新建banner.txt,里面放入想要打印的內容即可。

方式二:修改配置文件

spring: banner: location: file/bannerText.txt #文件位置 src/main/resources/file/bannerText.txt 圖片

和文本方式相同,但是圖片類型有限制,只能是以下三種gif,、jpg、png。
方式一:在src/main/resources下新建banner.png,里面放入想要打印的內容即可。

方式二:修改配置文件

spring: banner: image: location: file/bannerImage.png #文件位置 src/main/resources/file/bannerImage.png

打印效果

分享到:
標簽:SpringBoot
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定