SpringBoot 自定义Banner

SpringBoot自定义Banner

SpringBoot项目启动的时候会输出一个Spring的图标。

image-20240121135746569

思考🤔

  • 它是在哪个环节的时候输出的呢?
  • 是否可以自定义图标呢?

源码分析

通常我们SpringBoot项目是通过SpringBoot.run(Appcation.class)启动的。

run()

public ConfigurableApplicationContext run(String... args) {
		try {
            // 关键是这两行 
            // 第一行是初始化环境信息也就是会将我们配置文件中的内容,或者是System.getProperties()中的信息进行封装
			ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            // 通过环节信息来构建Banner并输出对于的内容
			Banner printedBanner = printBanner(environment);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, listeners);
			throw new IllegalStateException(ex);
		}
		return context;
}

printBanner()

private Banner.Mode bannerMode = Banner.Mode.CONSOLE;


private Banner printBanner(ConfigurableEnvironment environment) {
    	// 判断横幅的模式 是否为禁用 ,默认是输出到控制台
		if (this.bannerMode == Banner.Mode.OFF) {
			return null;
		}
		ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader
				: new DefaultResourceLoader(null);
    	// 创建一个SpringApplicationBannerPrinter对象
		SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);
    	// 判断横幅模式是否为输出到日志
		if (this.bannerMode == Mode.LOG) {
			return bannerPrinter.print(environment, this.mainApplicationClass, logger);
		}
    	// 默认情况会走到这里
		return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}

Banner.Mode

enum Mode {
		/**
		 * 禁用横幅的打印
		 */
		OFF,

		/**
		 * 将横幅输出到System.out
		 */
		CONSOLE,

		/**
		 * 将横幅输出到日志文件中
		 */
		LOG

	}

SpringApplicationBannerPrinter.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);
}

getBanner()

// 	private static final Banner DEFAULT_BANNER = new SpringBootBanner();
private Banner getBanner(Environment environment) {
		Banners banners = new Banners();
    	// 判断是否存在image的横幅
		banners.addIfNotNull(getImageBanner(environment));
    	// 判断是否存在文本的横幅
		banners.addIfNotNull(getTextBanner(environment));
		if (banners.hasAtLeastOneBanner()) {
			return banners;
		}
		if (this.fallbackBanner != null) {
			return this.fallbackBanner;
		}
    	// 这里如果在配置中没有得到Banner的话,则会使用SpringBoot默认的
		return DEFAULT_BANNER;
}
// 从当前环境中取出spring.banner.image.location 
// 判断这个路径下是否存在文件,存在则创建一个ImageBanner
// 不存在这尝试读取类路径下的banner.gif, banner.jpg", banner.png 
// 都不存在则返回一个NULL
private Banner getImageBanner(Environment environment) {
		String location = environment.getProperty("spring.banner.image.location");
		if (StringUtils.hasLength(location)) {
			Resource resource = this.resourceLoader.getResource(location);
			return resource.exists() ? new ImageBanner(resource) : null;
		}
		for (String ext : IMAGE_EXTENSION) {
			Resource resource = this.resourceLoader.getResource("banner." + ext);
			if (resource.exists()) {
				return new ImageBanner(resource);
			}
		}
		return null;
}

// 从当前环境中取出spring.banner.location配置的值 默认是banner.txt 可以自定义。通过这个路径来创建一个ResourceBanner
private Banner getTextBanner(Environment environment) {
		String location = environment.getProperty("spring.banner.location", "banner.txt");
		Resource resource = this.resourceLoader.getResource(location);
		try {
			if (resource.exists() && !resource.getURL().toExternalForm().contains("liquibase-core")) {
				return new ResourceBanner(resource);
			}
		}
		catch (IOException ex) {
			// Ignore
		}
		return null;
	}

SpringBootBanner

class SpringBootBanner implements Banner {

	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是一个字符串数组,实际打印的也就是这个数组的值。也就是我们的Spring图标以及一些版本信息。

小结

从源码中分析得出,在不配置spring.banner.locationspring.banner.image.location的情况下,SpringBoot默认会使用SpringBootBanner来进行输出。输出的则是Spring的图标。

当我们想自定义图标的话,则可以使用spring.banner.location来指定一个横幅文件的位置,或者直接在类路径下创建一个banner.txt,并把横幅的内容写入到里面。

实践

创建一个banner.txt,并写入程序员万岁!;

输出效果

image-20240121145819663

感觉很low😂。如何让他变的跟Spring那个图标一样好看呢。

Spring Boot自定义启动Banner在线生成工具

image-20240121145834309

替换banner.tet内容,效果。

image-20240121145909209

补充

纯字体的网站

  • (推荐)https://www.bootschool.net/ascii

  • http://patorjk.com/software/taag/

  • http://www.network-science.de/ascii/

图片风

  • (推荐)https://www.bootschool.net/ascii-art/animals

  • https://www.degraeve.com/img2txt.php

内置变量

  • spring-boot.version:SpringBoot的版本号
  • spring-boot.formatted-version:带v的版本号

image-20240121150844817

总结

https://www.bootschool.net/ascii-art/animals

  • https://www.degraeve.com/img2txt.php

内置变量

  • spring-boot.version:SpringBoot的版本号
  • spring-boot.formatted-version:带v的版本号

[外链图片转存中…(img-kzLyUrAu-1705820973870)]

总结

直接在类路径下创建banner.txt来替换SpringBoot默认的输出最为方便,想要美化的话,可以通过一些工具来进行生成。

  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

假女吖☌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值