springboot自定义banner的输出与源码解析
文章目录
- 一、介绍
- 二、演示环境
- 三、自定义banner
- 1. 文本
- 2. 图片
- 3. placeholder占位符
- 4. 关闭banner
- 四、源码分析
- 1. 关闭banner
- 2. banner模式
- 3. banner打印器
- 4. 打印banner
- ① 获取banner
- ② 打印banner
- 5. 版本号占位符的解析器
- 6. 文本格式占位符的解析器
- 7. 应用标题占位符的解析器
- 五、总结
一、介绍
Banner即横幅的意思,我们在庆祝某些事情时有些显眼包总会是拉个横幅以表明意图。
在我们启动springboot项目时,springboot往往也会打印出一个默认的横幅,该横幅中包含了一些信息如springboot版本号等,如下图所示。
既然有默认的,当然springboot也允许我们对banner进行自定义设置,如将banner设置为文本、图片,甚至关闭banner的输出。如下所示
是否略显炫酷?下面我们来介绍如何自定义banner,并通过源码进行分析。
二、演示环境
本演示项目的环境如下:
- java:1.8
- springboot:2.4.3
三、自定义banner
1. 文本
当我们需要自定义文本banner时,只需要在类路径classpath下新建一个文件,文件名为banner.txt
(springboot默认),然后编辑作为banner的文本即可,如下所示。
此时输出如下
如果不使用springboot默认的banner文件名,则需要通过在配置文件中配置spring.banner.location
,如下所示
如果文件的编码不是UTF-8,则可以在配置文件中通过spring.banner.charset
配置字符集,如下所示
spring:banner:location: fozuBanner.txtcharset: UTF-32
2. 图片
除了文本banner外,springboot还允许我们自定义图片banner。并且如果两种banner同时存在,则先输出图片banner、再输出文本banner。
默认地,springboot将从classpath类路径下获取banner.gif
、banner.jpg
、banner.png
作为图片banner。当然也可以通过在配置文件中配置spring.banner.image.location
来指定图片的位置。
在输出图片banner时,springboot将会把图片转化成ASCII艺术画输出,而非无脑式地将图片输出。
如下图所示,我们在类路径下添加图片,并将其命名为banner.png
。
启动项目后的输出如下
3. placeholder占位符
springboot允许我们在banner中使用${}
格式的占位符,但仅限于文本banner。内置的占位符有应用版本、springboot版本、字体样式、应用名。下面我们一一介绍。
-
应用版本
占位符为
${application.version}
或${application.formatted-version}
。springboot允许我们在文本banner中添加应用版本号。通过在文本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}
。获取当前项目使用的springboot的版本号,同样的,后者会给前者获取的值添加前缀
v
。如下图所示 -
字体样式
占位符为
${AnsiColor.NAME}
、${AnsiBackground.NAME}
、${AnsiStyle.NAME}
。当我们使用
${AnsiColor.RED}
时,打印的字体将变成红色;使用${AnsiBackground.YELLOW}
时,背景颜色将变成黄色;使用${AnsiStyle.BOLD}
时,将打印粗体。如下图所示 -
应用名
占位符为
${application.title}
。springboot允许我们在文本banner中添加应用名称。通过在文本banner中添加
${application.title}
时,springboot从MANIFEST.MF
中读取Implementation-Title
的值。例如,
MANIFEST.MF
中Implementation-Title
的值为MyApp
,则Implementation-Title
得到的值为MyApp
。注意:该信息只有通过
Spring Boot launchers
方式启动时才会生效。
4. 关闭banner
我们介绍了文本banner、图片banner后,接下来介绍如何关闭banner,关闭bannner后在项目启动时便不再输出banner。
方法当然也很简单,对于关闭bannner功能,springboot在SpringApplication
类中提供了响应的方法setBannerMode()
来关闭banner。下面对我们的主启动类进行修改。
-
修改前
public static void main(String[] args){SpringApplication.run(BannerApplication.class, args); }
-
修改后
public static void main(String[] args){SpringApplication springApplication = new SpringApplication(BannerApplication.class);// 将bannner的模式设置为off,即关闭springApplication.setBannerMode(Banner.Mode.OFF);springApplication.run(args); }
-
启动项目
四、源码分析
我们知道springboot是通过SpringApplication
类中的run()
方法启动的,在该方法中调用printBanner()
方法打印banner,如下图所示
下面我们进入该方法
1. 关闭banner
在printBanner()
方法中我们首先看到对bannerMode
的判断,如果是OFF
,则直接返回null
。
if (this.bannerMode == Banner.Mode.OFF) {return null;
}
而前面我们在演示的时候提到过,springboot提供了对应的方法。
public void setBannerMode(Banner.Mode bannerMode) {this.bannerMode = bannerMode;
}
我们看一下Banner.Mode
为何物?
2. banner模式
Banner.Mode
表示为Banner
的模式,springboot提供了三种模式:OFF关闭、CONSOLE控制台、LOG日志文件。
springboot默认的banner模式为CONSOLE控制台。
3. banner打印器
在printBanner()
方法中创建了banner打印器实例,代码如下所示
private Banner printBanner(ConfigurableEnvironment environment) {// ...SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);// ...
}
在调用构造方法实例化打印器时,传入资源加载器 和 兜底banner,兜底banner的含义为如果项目中没有指定的文本banner或图片banner时,则使用兜底banner,如果兜底banner依然不存在,最后才使用springboot默认banner。
springboot提供了设置兜底banner的方法:
public void setBanner(Banner banner) {this.banner = banner;
}
与设置banner模式相同,在主启动类中设置一个自定义的banner,该自定义banner必须实现Banner
接口的printBanner()
方法。
public static void main(String[] args){SpringApplication springApplication = new SpringApplication(BannerApplication.class);springApplication.setBanner(new CustomBanner());springApplication.run(args);
}
4. 打印banner
在完成banner打印器的实例化以后,就开始调用打印器的print()
方法对banner进行打印了,且打印器提供了两个重载的的print()
方法,分别用于日志模式和控制台模式。这两个重载方法的不同之处在第三个参数。如下所示
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、返回结果。我们以控制台模式的print()
方法为例。
Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {// 获取bannerBanner banner = getBanner(environment);// 打印bannerbanner.printBanner(environment, sourceClass, out);// 返回结果return new PrintedBanner(banner, sourceClass);
}
① 获取banner
我们进入getBanner()
方法查看其实现
该实现逻辑也很清晰,就是先后获取图片banner添加到banners中,如果banners中存在banner,则返回;否则返回兜底banner;如果兜底banner还不存在,则返回默认banner。
-
获取图片banner
获取到的图片banner用
ImageBanner
对象表示。 -
获取文本banner
获取到的文本banner用
ResourceBanner
对象表示。 -
兜底banner
前面我们在介绍banner打印器时,已经详细介绍过了。
-
默认banner
默认banner使用常量
DEFAULT_BANNER
表示为SpringBootBanner
对象。如下所示进入
SpringBootBanner
后发现发现我们再熟悉不过的默认banner,原来藏在这里。
② 打印banner
前面在getBanner()
方法中获取到的banner集合被添加到Bannners
中,注意一下,类Banners
是Banner
的子类,在它实现的printBanner()
方法中,通过遍历内部的banner集合并调用printBanner()
方法对不同的banner进行打印。
下面我们对不同类型bannner的打印逻辑进行分析
-
图片banner
图片banner被封装在
ImageBanner
对象中,在打印图片banner时,会对java.awt.headless
的配置进行处理,然后再调用其重载方法真正地输出图片banner。下面我们点击重载
printBanner()
方法,查看其真正输出图片banner的逻辑。在该方法中,从配置中获取图片banner的宽高等基本样式,然后将其输出,在输出过程中将图片转为ASCII艺术图。
-
文本banner
文本banner被封装在
ResourceBanner
对象中,我们进入该类的printBanner()
方法。该方法逻辑为将文本banner按照配置文件中
spring.banner.charset
指定的字符集转换为对应的banner字符串;然后获取用于解析${}
形式的占位符的解析器集合,利用解析器处理banner字符串中的占位符。最后将处理后的banner字符串输出。下面我们看一下有哪些占位符解析器
从源码中,我们看到,有处理版本号的解析器、文本格式的解析器、应用标题的解析器。
5. 版本号占位符的解析器
获取版本号占位符的解析器是通过getVersionResolver()
方法完成的,如下图所示,可以看到springboot内置给我们获取应用版本号和springboot版本号的占位符。
6. 文本格式占位符的解析器
获取文本格式占位符的解析器是通过getAnsiResolver()
方法完成的。如下图所示,可以看到内置了多种设置文本格式的方式。
下面我们以设置文本格式和文本颜色为例
-
文本格式
文本格式通过
AnsiStyle
设置,所以我们点击其对应的AnsiStyle
类,发现我们可以设置的文本格式如下 -
文本颜色
文本颜色通过
AnsiColor
设置,所以我们点击其对应的AnsiColor
类,发现我们可以设置的文本颜色如下
7. 应用标题占位符的解析器
获取应用标题占位符的解析器是通过getTitleResolver()
方法完成的。如下图所示。
五、总结
- 优先级:图片、文本banner > 兜底banner > 默认bannner
- 文本banner可以添加内置的占位符如版本号、文本颜色、文本格式等。
- 图片banner的打印是将图片转为ASCII艺术图后打印的。
纸上得来终觉浅,绝知此事要躬行。
————————————————我是万万岁,我们下期再见————————————————
相关文章:

springboot自定义banner的输出与源码解析
文章目录 一、介绍二、演示环境三、自定义banner1. 文本2. 图片3. placeholder占位符4. 关闭banner 四、源码分析1. 关闭banner2. banner模式3. banner打印器4. 打印banner① 获取banner② 打印banner 5. 版本号占位符的解析器6. 文本格式占位符的解析器7. 应用标题占位符的解析…...

LeetCode 141.环形链表
文章目录 💡题目分析💡解题思路🔔接口源码💡深度思考❓思考1❓思考2 题目链接👉 LeetCode 141.环形链表👈 💡题目分析 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中…...

Spring-Bean的生命周期
目录 生命周期汇总 细分生命周期 1.实例化 2.属性赋值(依赖注入) 3.Aware接口 4.BeanPostProcessor接口 5.初始化 6.销毁 测试验证 类结构 业务类 测试类 生命周期汇总 Spring Bean 的生命周期见下图 (一定记忆好下图&#x…...

Cat(3):客户端集成—简单案例
接下来编写一个简单的springboot与Cat整合的案例 1 新建springboot项目 首先创建一个Spring Boot的初始化工程。只需要勾选web依赖即可。 2 添加 Maven 添加依赖 <dependency><groupId>com.dianping.cat</groupId><artifactId>cat-client</artifa…...

虚拟机/双系统Ubuntu扩容
虚拟机Ubuntu扩容 1.需要删除所有的快照 2.扩展虚拟机磁盘大小 虚拟机(M)→设置(s)→硬盘(SCSI)→扩展磁盘容量 3.Ubuntu内调整分区大小 安装gparted分区工具:sudo apt-get install gparted 启动gparted并resize分区 4.最后最好建一个快照,不然gg了…...

Nginx搭建本地服务器,无需购买服务器即可测试vue项目打包后的效果
一.前言 本文是在windows环境(Linux环境下其实也大同小异)下基于Nginx实现搭建本地服务器,手把手教你部署vue项目。 二.Nginx入门 1)下载安装 进入Nginx官网下载,选择stable版本下的windows版本下载即可 2)…...
SpringBoot 接口调用出现乱码解决 中文乱码
SpringBoot 接口调用出现乱码解决 package com.cxjg.mvc.util;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springfra…...

JDBC封装与设计模式
什么是 DAO ? Data Access Object(数据存取对象) 位于业务逻辑和持久化数据之间实现对持久化数据的访问 DAO起着转换器的作用,将数据在实体类和数据库记录之间进行转换。 ----------------------------------------------------- DAO模式的组成部分 …...
小程序扫描二维码获取网址,通过Jsoup进行解析
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 文章目录 前言 一、Jsoup是什么? 二、使用步骤 1.引入库 2.读入数据 总结 前言 vx开发小程序使用扫一扫时不同二维码展示的东西不一样,需要进行解析 提示&a…...

Kubernetes+EFK构建日志分析平台
目录 Elasticsearch产品介绍 Fluentd 工作原理 Kibana产品介绍 一、环境准备 前三个主机都要操作 1、主机初始化配置 2、部署docker环境 2、部署kubernetes集群 2.1、组件介绍 2.2、配置阿里云yum源 2.3、安装kubelet kubeadm kubectl 2.4、配置init-config.yaml …...
客服如何减轻工作压力?浅析客服压力管理方法
在现代商业领域中,客服是一项非常重要的工作,负责根据客户需求提供解决方案。客服工作不仅需要一定的专业知识和技能,还需要面对各种复杂、多变的情况,并拥有强大的应对压力的能力。客服从业人员的工作压力往往非常大,…...

知识储备--基础算法篇-二分搜索
1.前言 最近准备开始刷算法题了,搜了很多相关的帖子,下面三个很不错, 计算机视觉秋招准备过程看这个:计算机视觉算法工程师-秋招面经 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/399813916 复习深度学习相关…...

【MySQL系列】表内容的基本操作(增删查改)
「前言」文章内容大致是对MySQL表内容的基本操作,即增删查改。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、MySQL表内容的增删查改1.1 Create1.1.1 单行数据全列插入1.1.2 多行数据指定列插入1.1.3 插入否则更新1.1.4 数据替换 1.2 Ret…...

docker搭建LNMP
docker安装 略 下载镜像 nginx:最新版php-fpm:根据自己需求而定mysql:根据自己需求定 以下是我搭建LNMP使用的镜像版本 rootVM-12-16-ubuntu:/docker/lnmp/php/etc# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 8.0…...
未出现过的最小正整数
给定一个长度为 n 的整数数组,请你找出未在数组中出现过的最小正整数。 样例 输入1:[-5, 3, 2, 3]输出1:1输入2:[1, 2, 3]输出2:4数据范围 1≤n≤105 , 数组中元素的取值范围 [−109,109]。 代码: c…...

易服客工作室:WordPress是什么?初学者的解释
目录 什么是WordPress? WordPress可以制作什么类型的网站? 谁制作了WordPress?它已经存在多久了? 谁使用 WordPress? 白宫网站 微软 滚石乐队 为什么要使用 WordPress? WordPress 是免费且…...

2019年9月全国计算机等级考试真题(C语言二级)
2019年9月全国计算机等级考试真题(C语言二级) 第1题 1、“商品”与“顾客”两个实体集之间的联系一般是 A. 一对一 B. 一对多 C. 多对一 D. 多对多 正确答案:D 第2题 定义学生选修课程的关系模式:SC(S#,…...

LLaMA模型泄露 Meta成最大受益者
一份被意外泄露的谷歌内部文件,将Meta的LLaMA大模型“非故意开源”事件再次推到大众面前。“泄密文件”的作者据悉是谷歌内部的一位研究员,他大胆指出,开源力量正在填平OpenAI与谷歌等大模型巨头们数年来筑起的护城河,而最大的受益…...

企业中商业智能BI,常见的工具和技术
商业智能(Business Intelligence,简称BI)数据可视化是通过使用图表、图形和其他可视化工具来呈现和解释商业数据的过程。它旨在帮助组织更好地理解和分析他们的数据,从而做出更明智的商业决策。 常见的商业智能数据可视化工具和技…...

item_password-获得淘口令真实url
一、接口参数说明: item_password-获得淘口令真实url ,点击更多API调试,请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/taobao/item_password 名称类型必须描述keyString是调用key(…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...