springboot自定义banner的输出与源码解析

news2024/9/25 17:22:26

文章目录

  • 一、介绍
  • 二、演示环境
  • 三、自定义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.txt
    charset: UTF-32

2. 图片

除了文本banner外,springboot还允许我们自定义图片banner。并且如果两种banner同时存在,则先输出图片banner、再输出文本banner

默认地,springboot将从classpath类路径下获取banner.gifbanner.jpgbanner.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.MFImplementation-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.MFImplementation-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) {
    // 获取banner
    Banner banner = getBanner(environment);
    // 打印banner
    banner.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中,注意一下,类BannersBanner的子类,在它实现的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艺术图后打印的。


纸上得来终觉浅,绝知此事要躬行。

————————————————我是万万岁,我们下期再见————————————————

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/889939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows下, artemis学习

1. download artemis from apache ActiveMQhttps://activemq.apache.org/components/artemis/download/2. 解压缩到 C:/software/apache-artemis-2.30.0/ 2. 进入到cmd&#xff0c; 执行 C:\software\apache-artemis-2.30.0\bin>artemis create C:/software/apache-artem…

C语言实现将字典dict.txt上传到数据库中

代码 #include <stdio.h> #include <string.h> #include <unistd.h> #include <sqlite3.h>int do_insert(sqlite3 *db,char *word,char *mean);int main(int argc, const char *argv[]) {//以读的方式打开文件FILE* fpfopen("./dict.txt",&…

Android Studio run app 设置 release 模式

背景 为验证我们的 SDK 集成在客户应用上的质量&#xff0c;需要我们的测试环境尽量的与客户应用保持一致。客户普遍都会打 release 包并混淆&#xff0c;然后进行上线应用&#xff0c;因此我们在测试过程中也需要使用 release 包进行验证。对于 Android Studio 运行项目&…

基于web的旅游管理系统/旅游网站的设计与实现

摘要 随着计算机技术&#xff0c;网络技术的迅猛发展&#xff0c;Internet 的不断普及&#xff0c;网络在各个领域里发挥了越来越重要的作用。特别是随着近年人民生活水平不断提高&#xff0c;在线旅游给景区商家的业务带来了更大的发展机遇。 在经济快速发展的带动下&#xff…

这6个免费设计素材网站,设计师都在用,马住

新手设计师不知道去哪里找素材&#xff0c;那就看看这几个设计师都在用的网站吧&#xff0c;免费、付费、商用素材都有&#xff0c;可根据需求选择&#xff0c;赶紧收藏~ 菜鸟图库 https://www.sucai999.com/?vNTYxMjky 菜鸟图库是一个非常大的素材库&#xff0c;站内包含设…

如何做好意大利语翻译,北京翻译哪里比较专业?

意大利语被誉为世界上最美的语言之一&#xff0c;在国内应用广泛&#xff0c;市场对意大利语翻译的需求量也很大。那么&#xff0c;如何做好意大利语翻译&#xff0c;北京翻译哪里比较专业&#xff1f; 业内人士指出&#xff0c;要想做好意大利语翻译&#xff0c;首先要充分理解…

【C语言】动态通讯录 -- 详解

⚪前言 前面详细介绍了静态版通讯录【C语言】静态通讯录 -- 详解_炫酷的伊莉娜的博客-CSDN博客&#xff0c;但是静态版通讯录的空间是无法被改变的&#xff0c;而且空间利用率也不高。为了解决静态通讯录这一缺点&#xff0c;这时就要有一个能够随着存入联系人数量的增加而增大…

Maven之tomcat7-maven-plugin 版本低的问题

tomcat7-maven-plugin 版本『低』的问题 相较于当前最新版的 tomcat 10 而言&#xff0c;tomcat7-maven-plugin 确实看起来很显老旧。但是&#xff0c;这个问题并不是问题&#xff0c;至少不是大问题。 原因 1&#xff1a;tomcat7-maven-plugin 仅用于我们&#xff08;程序员&…

为什么企业需要内部威胁检测软件?

在数字时代&#xff0c;企业不仅需要抵御外部威胁&#xff0c;还必须密切关注内部威胁&#xff0c;因为内部因素可能对数据安全造成严重威胁。作为一款强大的内部威胁监测工具&#xff0c;ADAudit Plus 在这一领域发挥着关键作用。本文将深入探讨 ADAudit Plus 在内部威胁监测中…

AUTOSAR NvM Block的三种类型

Native NVRAM block Native block是最基础的NvM Block&#xff0c;可以用来存储一个数据&#xff0c;可以配置长度、CRC等。 Redundant NVRAM block Redundant block就是在Native block的基础上再加一个冗余块&#xff0c;当Native block失效&#xff08;读取失败或CRC校验失…

如何使用PHP开发网页定时刷新功能

如何使用PHP开发网页定时刷新功能 随着互联网的发展&#xff0c;越来越多的网站需要实时更新显示数据。而实时刷新页面是一种常见的需求&#xff0c;它可以让用户在不刷新整个页面的情况下获得最新的数据。本文将介绍如何使用PHP开发网页定时刷新功能&#xff0c;并提供代码示…

带你了解Cloudquery 安装使用功能

&#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x1f609;&#x1f609; &#x1f495;欢迎大家&#xff1a;这里是CSDN&#xff0c;我总结…

以 Java NIO 的角度理解 Netty

文章目录 前言Java NIO 工作原理Selector 的创建ServerSocketChannel 的创建ServerSocketChannel 注册 Selector对事件的处理总结 前言 上篇文章《Netty 入门指南》主要涵盖了 Netty 的入门知识&#xff0c;包括 Netty 的发展历程、核心功能与组件&#xff0c;并且通过实例演示…

剑指 Offer 60. n个骰子的点数(动态规划)

文章目录 题目描述思路分析完整代码 题目描述 把n个骰子扔在地上&#xff0c;所有骰子朝上一面的点数之和为s。输入n&#xff0c;打印出s的所有可能的值出现的概率。 你需要用一个浮点数数组返回答案&#xff0c;其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那…

Status 技术的兴衰:从问世到淘汰的历程

标题 Status 技术的兴衰&#xff1a;从问世到淘汰的历程摘要引言Status 问世初期优势挑战 Status 高峰期优势挑战 Status 面临挑战挑战 新兴技术的涌现优势 淘汰的原因结论 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1f466;&#x1f3fb; 《java 面试…

排污口水质的在线监测,实时掌握排口水质助力生态治理

水是生命之源&#xff0c;良好的水生态环境是社会发展的必然要求。然而随着工业化和城市化的发展&#xff0c;人类面临空气和水环境污染等严峻挑战&#xff0c;其中水环境问题尤为突出。排污成为城市和工业生产过程中不可避免的环保问题。 为加快解决生态环境突出问题&#xff…

搞科研需要具备哪些特质?

你认为科研人员需要具备哪些特质才能实现成为大科学家的梦想&#xff1f;回顾那些成功科学家的经历&#xff0c;发现他们身上总会一些共性&#xff0c;正是拥有这些共性&#xff0c;他们最后都在领域内取得了成功。那么&#xff0c;到底都具备哪些共性呢&#xff1f; 好奇心。小…

手把手教你如何挑选适合你的AI编程辅助工具

ChatGPT的普及引发了对AI应用场景的探索和实践的重大变革&#xff0c;垂直领域专业类大模型正正在不断深化落地&#xff0c;其中基于大模型专注于编码的AI工具的出现显著降低了开发的复杂性&#xff0c;提高了开发人员的开发效率&#xff0c;对初级开发人员尤其有帮助。 因此面…

面试官三连问:给我讲讲什么是索引覆盖?什么是索引下推 ? 什么是最左匹配原则 ?

1.什么是索引覆盖 索引覆盖是指在一个查询语句中&#xff0c;某个索引已经 "覆盖了" 需要被查询出来的列&#xff0c;此时就不需要进行回表查询了&#xff0c;这就叫做索引覆盖&#xff01;&#xff01;&#xff08;索引覆盖它是非聚簇索引中的一个特殊情况&#xff…

3.2.0 版本预告!远程日志解决 Worker 故障获取不到日志的问题

Apache DolphinScheduler 3.2.0 版本已经呼之欲出&#xff0c;8 月 中下旬&#xff0c;这个大版本就要和用户见面了。为了让大家提前了解到此版本更新的主要内容&#xff0c;我们已经制作了几期视频和内容做了大致介绍&#xff0c;包括《重磅预告&#xff01;Apache DolphinSch…