SpringBoot源码剖析之自定义Banner

一、什么是Banner

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


  .   ____          _            __ _ _

 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

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

 =========|_|==============|___/=/_/_/_/

 :: 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

三、源码剖析

那么SpringBoot是如何实现的呢?

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

SpringApplication.printBanner


private Banner printBanner(ConfigurableEnvironment environment) {

    检查打印Banner的开关是否启

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

 return null;

 }

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

   : new DefaultResourceLoader(getClassLoader());

 //准备printer

 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有三种:

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

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

  • LOG 打印Banner到日志文件中

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

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

SpringApplicationBannerPrinter.print


public Banner print(Environment environment, Class sourceClass, PrintStream out) {

    //获取banner

 Banner banner = getBanner(environment);

 //打印banner

 banner.printBanner(environment, sourceClass, out);

 return new PrintedBanner(banner, sourceClass);

}

SpringApplicationBannerPrinter.getBanner


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;

 }

 return DEFAULT_BANNER;

}

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

SpringApplicationBannerPrinter.printBanner


 public void printBanner(Environment environment, Class sourceClass, PrintStream out) {

 for (Banner banner : this.banners) {

   banner.printBanner(environment, sourceClass, out);

 }

 }

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

四、源码总结

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

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

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

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

你可能感兴趣的:(SpringBoot源码剖析之自定义Banner)