一定要知道的SpringBoot源码剖析之自定义Banner

一、什么是Banner

当我们启动一个SpringBoot应用之后,经常会在控制台看到如下打印

  1.   .   ____          _            __ _ _

  2.  
  3.  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

  4.  
  5. ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

  6.  
  7.  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

  8.  
  9.   '  |____| .__|_| |_|_| |_\__, | / / / /

  10.  
  11.  =========|_|==============|___/=/_/_/_/

  12.  
  13.  :: Spring Boot ::        (v2.1.6.RELEASE)

该输出就是Banner,看起来像是一个项目的标志一样。

二、如何自定义Banner

如果想让自己项目的banner打印自己想要的图案:例如公司LOGO等,应该要怎么办呢?

很简单,只需要在SpringBoot工程的 /src/main/resources 目录下创建一个名为 banner.txt 的文件即可,这样,容器在启动时就会将此文件中的文本打印在控制台啦。

那么怎么来绘制一些图案呢?现在有很多现成的网站支持设计banner,可以参考

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

输入文本进行转化

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

输入文本进行转化

3.http://www.degraeve.com/img2txt.php

可以将一个图片转为文字格式图画

image

image

三、源码剖析

那么SpringBoot是如何实现的呢?

在SpringApplication的run方法中,有一行Banner printedBanner = printBanner(environment);在该方法中进行banner的获取和打印。

SpringApplication.printBanner

  1. private Banner printBanner(ConfigurableEnvironment environment) {

  2.  
  3.     检查打印Banner的开关是否启

  4.  
  5.  if (this.bannerMode == Banner.Mode.OFF) {

  6.  
  7.  return null;

  8.  
  9.  }

  10.  
  11.  ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader

  12.  
  13.    : new DefaultResourceLoader(getClassLoader());

  14.  
  15.  //准备printer

  16.  
  17.  SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);

  18.  
  19.  //打印在日志中

  20.  
  21.  if (this.bannerMode == Mode.LOG) {

  22.  
  23.  return bannerPrinter.print(environment, this.mainApplicationClass, logger);

  24.  
  25.  }

  26.  
  27.  //打印在控制台

  28.  
  29.  return bannerPrinter.print(environment, this.mainApplicationClass, System.out);

  30.  
  31. }

Banner.Mode有三种:

  • OFF 不进行任何形式的Banner输出

  • CONSOLE 在控制台进行Banner的打印

  • LOG 打印Banner到日志文件中

SpringApplication中默认Banner.Mode类型为CONSOLE。

ResourceLoader是spring提供用于获取classpath下或者resource目录下资源的策略接口。在拿到ResourceLoader之后将其封装为SpringApplicationBannerPrinter。之后调用其print方法。

SpringApplicationBannerPrinter.print

  1. public Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {

  2.  
  3.     //获取banner

  4.  
  5.  Banner banner = getBanner(environment);

  6.  
  7.  //打印banner

  8.  
  9.  banner.printBanner(environment, sourceClass, out);

  10.  
  11.  return new PrintedBanner(banner, sourceClass);

  12.  
  13. }

SpringApplicationBannerPrinter.getBanner

  1. private Banner getBanner(Environment environment) {

  2.  
  3.  Banners banners = new Banners();

  4.  
  5.  banners.addIfNotNull(getImageBanner(environment));

  6.  
  7.  banners.addIfNotNull(getTextBanner(environment));

  8.  
  9.  if (banners.hasAtLeastOneBanner()) {

  10.  
  11.  return banners;

  12.  
  13.  }

  14.  
  15.  if (this.fallbackBanner != null) {

  16.  
  17.  return this.fallbackBanner;

  18.  
  19.  }

  20.  
  21.  return DEFAULT_BANNER;

  22.  
  23. }

从getBanner代码中看,不仅支持txt形式的banner,也支持图片资源banner。查看getImageBanner(environment)方法实现,可知SpringBoot将从spring.banner.image.location属性中获取图片路径,支持gif,jpg,png,然后封装为ImageBanerr。其中Banners实质是维护了一个banner列表。在真正打印的时候进行遍历打印。

SpringApplicationBannerPrinter.printBanner

  1.  public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {

  2.  
  3.  for (Banner banner : this.banners) {

  4.  
  5.    banner.printBanner(environment, sourceClass, out);

  6.  
  7.  }

  8.  
  9.  }

所有springboot同时也支持多个banner的打印。

四、源码总结

从源码中我们可以知道更多有关banner的支持,下面将列述

  • 默认自定义banner,只需要在resource目录下放置一个banner.txt文件即可,如果不想命名为banner.txt,则可以指定属性spring.banner.location为自定义文件名即可

  • 支持图片资源banner。指定属性spring.banner.image.location为图片资源路径

  • SpringBoot支持同时配置txt形式和图片形式banner,并同时打印。

猜你喜欢

转载自blog.csdn.net/weixin_48673251/article/details/109077687
今日推荐