紧扣主题,先看负责控制台打印的方法 。
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只能通过构造器进行注入 。
推荐阅读
- dota2英文配音启动项 dota2英文配音
- 电动机星三角启动原理接线图 电动机星三角启动
- 手掌启动仪式视频 手掌视频
- 光环战役如何开控制台 光晕战争攻略
- 应用程序无法启动 并行配置不正确
- 将门毒后|《将门毒后》宣发启动,谢景行人选受赞,沈妙一角却被指形象不搭
- u盘bios设置usb启动 bios设置usb启动
- 怎么进入bios设置界面设置u盘启动?怎么进入bios界面?
- 开机启动项怎么设置win11 开机启动项
- 电脑开机启动设置 开机启动设置