百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

太香了!女朋友熬夜帮我整理的Spring Boot - Banner 笔记,分享给你

yuyutoo 2025-04-09 22:24 30 浏览 0 评论

上一篇分享的是《Java避坑指南!IDEA查看.class文件源码下载失败问题汇总》,这篇给大家分享《Spring Boot - 自定义 Banner 图案》。

前言

我们在启动 Spring Boot 项目时,默认会在控制台打印 Spring logo 和版本等信息,如下:

这就是 Spring Boot 的 Banner 打印功能,其实我们可以自定义打印的 banner ,也可以禁用和启用打印 banner 功能。在真实项目中,我们一般不会去自定义 banner 图案,它其实就是项目启动时打印图案或者文字而已,没实际意义。推荐在自己个人项目玩玩这个彩蛋即可,顺便简单了解下它内部实现原理。

比如,自定义一个 banner 之后,项目启动控制台打印如下所示:

实现原理

Spring Boot 有一个接口
org.springframework.boot.Banner
专门实现这个操作。要想自定义打印 banner ,只要自定义一个类实现这个接口,重写 printBanner 方法进行打印即可。Springboot 项目启动时,会创建我们的实现类对象,并调用对象的 printBanner 方法。

package org.springframework.boot;
import java.io.PrintStream;
import org.springframework.core.env.Environment;
/**
 * Interface class for writing a banner programmatically.
 * 用于以编程方式编写 banner 的接口类
 * @since 1.2.0
 */
@FunctionalInterface
public interface Banner {
	/**
	 * Print the banner to the specified print stream.
	 * 将 banner 打印到指定的打印流。
	 * @param environment the spring environment
	 * @param sourceClass the source class for the application
	 * @param out the output print stream
	 */
	void printBanner(Environment environment, Class sourceClass, PrintStream out);
	// 用于配置Banner的的枚举值
	enum Mode {
		// 关闭 banner 打印
		OFF,
        // 打印 banner 到 控制台
		CONSOLE,
		// 打印 banner 到日志文件
		LOG
	}
}

默认 Banner 实现类

Springboot 已经有几个自带的 Banner 实现类,Springboot 启动时会根据条件选择不同的 Banner 实现类进行打印 banner 信息。主要是 ImageBannerResourceBannerSpringBootBanner 这三个实现类。

  1. 项目启动时,会判断是否某些条件成立(项目中是否存在 banner 文件),成立则创建 ImageBannerResourceBanner 类对象,并且使用它们来打印 banner。
  2. 如果不成立检查是否存在我们自定义的 Banner 实现类 fallbackBanner,如果存在则使用它来打印 banner 图案。
  3. 否则,则使用默认的 SpringBootBanner 实现类来打印 banner,也就是我们经常看到 Spring 图案。
// 获取可用的 Banner 实现类
private Banner getBanner(Environment environment) {
	Banners banners = new Banners();
	banners.addIfNotNull(getImageBanner(environment));
	banners.addIfNotNull(getTextBanner(environment));
	if (banners.hasAtLeastOneBanner()) {
		return banners;
	}
	if (this.fallbackBanner != null) {
		return this.fallbackBanner;
	}
	// SpringBootBanner 实现类
	return DEFAULT_BANNER;
}

ImageBanner


org.springframework.boot.ImageBanner
类是专门加载和打印图片 banner 的。它检查配置文件 application.proeprties 是否有配置的
spring.banner.image.location
变量的值,这个值可用来指定要加载的图片,如果存在则构建 ImageBanner 对象。如果没有配置变量,则还会检查 Classpath 下是否存在以 banner 开头,以 .gif.jpg.png 结尾的图片文件,如果有也会构建 ImageBanner 对象。

class SpringApplicationBannerPrinter {
	static final String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";
	static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };
	// 获取 ImageBanner 对象
	private Banner getImageBanner(Environment environment) {
	    // 加载 spring.banner.image.location 指定的文件,文件存在则构建 ImageBanner 对象
		String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
		if (StringUtils.hasLength(location)) {
			Resource resource = this.resourceLoader.getResource(location);
			return resource.exists() ? new ImageBanner(resource) : null;
		}
		// 查找 banner.gif,banner.jpg,banner.png 文件
		for (String ext : IMAGE_EXTENSION) {
			Resource resource = this.resourceLoader.getResource("banner." + ext);
			if (resource.exists()) {
				return new ImageBanner(resource);
			}
		}
		return null;
	}
}

ResourceBanner


org.springframework.boot.ResourceBanner
类是专门加载和打印字符 banner 的。它检查配置文件 application.proeprties 是否有配置的 spring.banner.location 变量的值,这个值可用来指定要加载的文件,如果存在则构建 ResourceBanner 对象。如果没有配置变量,则还会检查资源路径下是否存在 banner.txt 文件,如果存在也会构建 ResourceBanner 对象。

class SpringApplicationBannerPrinter {
	static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
	static final String DEFAULT_BANNER_LOCATION = "banner.txt";
	// 获取 ResourceBanner 对象
	private Banner getTextBanner(Environment environment) {
		String location = environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION);
		Resource resource = this.resourceLoader.getResource(location);
		if (resource.exists()) {
			return new ResourceBanner(resource);
		}
		return null;
	}
}

如果想要自定义 banner,我们一般在项目的 resources 资源目录下创建 banner.txt 文件,然后在里面填入我们想要的打印的文字内容即可。例如我在 banner.txt 文件中填充了 Chen Pi 内容,然后启动项目。

SpringBootBanner

如果项目没有设置以上两种自定义的 banner(ImageBanner 和 ResourceBanner),则默认情况下,会使用 SpringBootBanner 实现类打印 banner ,也就是我们启动 Springboot 项目时在控制台看到的打印 Spring 图案。源码如下:

package org.springframework.boot;
import java.io.PrintStream;
import org.springframework.boot.ansi.AnsiColor;
import org.springframework.boot.ansi.AnsiOutput;
import org.springframework.boot.ansi.AnsiStyle;
import org.springframework.core.env.Environment;
/**
 * Default Banner implementation which writes the 'Spring' banner.
 */
class SpringBootBanner implements Banner {
	// 这个就是我们启动 Springboot 项目时在控制台看到的图案
	private static final String[] BANNER = { "", "  .   ____          _            __ _ _",
			" /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\", "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
			" \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )", "  '  |____| .__|_| |_|_| |_\\__, | / / / /",
			" =========|_|==============|___/=/_/_/_/" };
	private static final String SPRING_BOOT = " :: Spring Boot :: ";
	private static final int STRAP_LINE_SIZE = 42;
	@Override
	public void printBanner(Environment environment, Class sourceClass, PrintStream printStream) {
		for (String line : BANNER) {
			printStream.println(line);
		}
		String version = SpringBootVersion.getVersion();
		version = (version != null) ? " (v" + version + ")" : "";
		StringBuilder padding = new StringBuilder();
		while (padding.length() < STRAP_LINE_SIZE - (version.length() + SPRING_BOOT.length())) {
			padding.append(" ");
		}
		printStream.println(AnsiOutput.toString(AnsiColor.GREEN, SPRING_BOOT, AnsiColor.DEFAULT, padding.toString(),
				AnsiStyle.FAINT, version));
		printStream.println();
	}
}

实现 Banner 类

前面说我们可以实现 Banner 类,重写打印方法,实现自定义 banner 打印功能。

package com.chenpi;
import java.io.PrintStream;
import org.springframework.boot.Banner;
import org.springframework.core.env.Environment;
/**
 * @Description 自定义 Banner 实现类
 * @Author Mr.nobody
 * @Date 2021/6/4
 * @Version 1.0
 */
public class MyBanner implements Banner {
    @Override
    public void printBanner(Environment environment, Class sourceClass, PrintStream out) {
      String banner = "       .__                           .__ \n"
          + "  ____ |  |__   ____   ____   ______ |__|\n"
          + "_/ ___\\|  |  \\_/ __ \\ /    \\  \\____ \\|  |\n"
          + "\\  \\___|   Y  \\  ___/|   |  \\ |  |_> >  |\n"
          + " \\___  >___|  /\\___  >___|  / |   __/|__|\n"
          + "     \\/     \\/     \\/     \\/  |__|       ";
      out.println(banner);
    }
}

创建自定义的 Banner 实现类对象,设置到 SpringApplication 类对象的 banner 属性,最终这个属性的值会会被赋值到
SpringApplicationBannerPrinter
对象的 fallbackBanner 属性中,感兴趣的可以启动 debug 跟踪下。

package com.chenpi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootBannerApplication {
	public static void main(String[] args) {
		SpringApplication springApplication = new SpringApplication(SpringBootBannerApplication.class);
		// 设置自定义 Banner
		springApplication.setBanner(new MyBanner());
		// 启动 SpringBoot
		springApplication.run(args);
	}
}

Banner 样式控制

文章一开始的佛祖图形,你会发现是翠绿色的。其实 Springboot 支持我们修改 banner 的颜色,字体斜体,粗体等样式。SpringBoot 为我们提供了三个枚举类来设定这些样式。

  1. AnsiColor:设定字符的前景色;参考 org.springframework.boot.ansi.AnsiColor 枚举类。
  2. AnsiBackground:设定字符的背景色;参考 org.springframework.boot.ansi.AnsiBackground 枚举类。
  3. AnsiStyle:设定字符的加粗、斜体、下划线等等;参考 org.springframework.boot.ansi.AnsiStyle 枚举类。

而且,在 banner.txt 文件中还可以引用一些全局变量,例如:

  1. ${spring-boot.version}:Spring Boot 版本号;
  2. ${spring-boot.formatted-version}:格式化后的 Spring Boot 版本号信息。
  3. ${application.version}:MANIFEST.MF 文件中的版本号;
  4. ${application.formatted-version}:格式化后的 MANIFEST.MF 文件中的版本号信息;

不仅如此,还可以引用我们在配置文件 application.properties 中定义的变量,例如在配置文件中定义了如下变量:

application.auth=chenpi

定义的 banner.txt 文件内容如下:

${AnsiColor.BRIGHT_GREEN}
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//            佛祖保佑       永不宕机     永无BUG                     //
////////////////////////////////////////////////////////////////////
${AnsiColor.BRIGHT_CYAN}
Application Version: ${application.version}${application.formatted-version}
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}
By -- ${application.auth}

启动项目,会在控制台打印的 banner 如下:

Banner 模式

在 Banner 接口中有定义一个枚举类,这个枚举定义了配置 Banner 的可能枚举值,如下:

@FunctionalInterface
public interface Banner {
	// 用于配置Banner的的枚举值
	enum Mode {
		// 关闭 banner 打印
		OFF,
        // 打印 banner 到 控制台
		CONSOLE,
		// 打印 banner 到日志文件
		LOG
	}
}

所以我们可以选择关闭 banner,banner 打印到控制台还是日志文件,如下:

package com.chenpi;
import org.springframework.boot.Banner.Mode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootBannerApplication {
    public static void main(String[] args) {
         SpringApplication springApplication = new SpringApplication(SpringBootBannerApplication.class);
         // 关闭 banner
         springApplication.setBannerMode(Mode.OFF);
         // 启动 SpringBoot
         springApplication.run(args);
    }
}

也可以配置文件中设置此值,如下

spring.main.banner-mode=off

如果启动类跟配置文件中都配置了对banner开关的设置,配置文件中设置的banner开关会优先于启动类中设置的开关。

  • 以上就是《Spring Boot - 自定义 Banner 图案》的分享。
  • 也欢迎大家交流探讨,该文章若有不正确的地方,希望大家多多包涵。
  • 创作不易,你们的支持就是我最大的动力,如果对大家有帮忙给个赞哦~~~

更多资料,私信回复【666】......

相关推荐

《保卫萝卜2》安卓版大更新 壕礼助阵世界杯

《保卫萝卜2:极地冒险》本周不仅迎来了安卓版本的重大更新,同时将于7月4日本周五,带来“保卫萝卜2”安卓版本世界杯主题活动的火热开启,游戏更新与活动两不误。一定有玩家会问,激萌塔防到底进行了哪些更新?...

儿童手工折纸:胡萝卜,和孩子一起边玩边学carrot

1、准备两张正方形纸,一橙一绿,对折出折痕。2、橙色沿其中一条对角线如图折两三角形。3、把上面三角折平,如图。4、绿色纸折成三角形。5、再折成更小的三角形。6、再折三分之一如图。7、打开折纸,压平中间...

《饥荒》食物代码有哪些(饥荒最新版代码总汇食物篇)

饥荒游戏中,玩家们需要获取各种素材与食物,进行生存。玩家们在游戏中,进入游戏后按“~”键调出控制台使用代码,可以直接获得素材。比如胡萝卜的代码是carrot,玉米的代码是corn,南瓜的代码是pump...

Skyscanner:帮你找到最便宜机票 订票不求人

你喜欢旅行吗?在合适的时间、合适的目的地,来一场说走就走的旅行?机票就是关键!Skyscanner这款免费的手机应用,在几秒钟内比较全球600多家航空公司的航班安排、价格和时刻表,帮你节省金钱和时间。...

小猪佩奇第二季50(小猪佩奇第二季英文版免费观看)

Sleepover过夜Itisnighttime.现在是晚上。...

我在民政局工作的那些事儿(二)(我在民政局上班)

时间到了1997年的秋天,经过一年多的学习和实践,我在处理结婚和离婚的事情更加的娴熟,也获得了领导的器重,所以我在处理平时的工作时也能得心应手。这一天我正在离婚处和同事闲聊,因为离婚处几天也遇不到人,...

夏天来了就你还没瘦?教你不节食13天瘦10斤的哥本哈根减肥法……

好看的人都关注江苏气象啦夏天很快就要来了你是否和苏苏一样身上的肉肉还没做好准备?真是一个悲伤的故事……下面这个哥本哈根减肥法苏苏的同事亲测有效不节食不运动不反弹大家快来一起试试看吧~DAY1...

Pursuing global modernization for peaceful development, mutually beneficial cooperation, prosperity for all

AlocalworkeroperatesequipmentintheChina-EgyptTEDASuezEconomicandTradeCooperationZonei...

Centuries-old tea road regains glory as Belt and Road cooperation deepens

FUZHOU/ST.PETERSBURG,Oct.2(Xinhua)--NestledinthepicturesqueWuyiMountainsinsoutheastChi...

15 THE NUTCRACKERS OF NUTCRACKER LODGE (CONTINUED)胡桃夹子小屋里的胡桃夹子(续篇)

...

AI模型部署:Triton Inference Server模型部署框架简介和快速实践

关键词:...

Ftrace function graph简介(flat function)

引言由于android开发的需要与systrace的普及,现在大家在进行性能与功耗分析时候,经常会用到systrace跟pefetto.而systrace就是基于内核的eventtracing来实...

JAVA历史版本(java各版本)

JAVA发展1.1996年1月23日JDK1.0Java虚拟机SunClassicVM,Applet,AWT2.1997年2月19日JDK1.1JAR文件格式,JDBC,JavaBea...

java 进化史1(java的进阶之路)

java从1996年1月第一个版本诞生,到2022年3月最新的java18,已经经历了27年,整整18个大的版本。很久之前有人就说java要被淘汰,但是java活到现在依然坚挺,不知道java还能活...

学习java第二天(java学完后能做什么)

#java知识#...

取消回复欢迎 发表评论: