当前位置: 首页 > news >正文

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.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) {// 获取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中,注意一下,类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艺术图后打印的。


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

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

相关文章:

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

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

LeetCode 141.环形链表

文章目录 &#x1f4a1;题目分析&#x1f4a1;解题思路&#x1f514;接口源码&#x1f4a1;深度思考❓思考1❓思考2 题目链接&#x1f449; LeetCode 141.环形链表&#x1f448; &#x1f4a1;题目分析 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中…...

Spring-Bean的生命周期

目录 生命周期汇总 细分生命周期 1.实例化 2.属性赋值&#xff08;依赖注入&#xff09; 3.Aware接口 4.BeanPostProcessor接口 5.初始化 6.销毁 测试验证 类结构 业务类 测试类 生命周期汇总 Spring Bean 的生命周期见下图 &#xff08;一定记忆好下图&#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分区工具&#xff1a;sudo apt-get install gparted 启动gparted并resize分区 4.最后最好建一个快照&#xff0c;不然gg了…...

Nginx搭建本地服务器,无需购买服务器即可测试vue项目打包后的效果

一.前言 本文是在windows环境&#xff08;Linux环境下其实也大同小异&#xff09;下基于Nginx实现搭建本地服务器&#xff0c;手把手教你部署vue项目。 二.Nginx入门 1&#xff09;下载安装 进入Nginx官网下载&#xff0c;选择stable版本下的windows版本下载即可 2&#xff09;…...

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 &#xff1f; Data Access Object(数据存取对象) 位于业务逻辑和持久化数据之间实现对持久化数据的访问 DAO起着转换器的作用&#xff0c;将数据在实体类和数据库记录之间进行转换。 ----------------------------------------------------- DAO模式的组成部分 …...

小程序扫描二维码获取网址,通过Jsoup进行解析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、Jsoup是什么&#xff1f; 二、使用步骤 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 …...

客服如何减轻工作压力?浅析客服压力管理方法

在现代商业领域中&#xff0c;客服是一项非常重要的工作&#xff0c;负责根据客户需求提供解决方案。客服工作不仅需要一定的专业知识和技能&#xff0c;还需要面对各种复杂、多变的情况&#xff0c;并拥有强大的应对压力的能力。客服从业人员的工作压力往往非常大&#xff0c;…...

知识储备--基础算法篇-二分搜索

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

【MySQL系列】表内容的基本操作(增删查改)

「前言」文章内容大致是对MySQL表内容的基本操作&#xff0c;即增删查改。 「归属专栏」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 的整数数组&#xff0c;请你找出未在数组中出现过的最小正整数。 样例 输入1&#xff1a;[-5, 3, 2, 3]输出1&#xff1a;1输入2&#xff1a;[1, 2, 3]输出2&#xff1a;4数据范围 1≤n≤105 , 数组中元素的取值范围 [−109,109]。 代码&#xff1a; c…...

易服客工作室:WordPress是什么?初学者的解释

目录 什么是WordPress&#xff1f; WordPress可以制作什么类型的网站&#xff1f; 谁制作了WordPress&#xff1f;它已经存在多久了&#xff1f; 谁使用 WordPress&#xff1f; 白宫网站 微软 滚石乐队 为什么要使用 WordPress&#xff1f; WordPress 是免费且…...

2019年9月全国计算机等级考试真题(C语言二级)

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

LLaMA模型泄露 Meta成最大受益者

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

企业中商业智能BI,常见的工具和技术

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

item_password-获得淘口令真实url

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

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...