SpringBoot之自定义Banner详解

 

1、在线生成banner网站

https://www.bootschool.net/ascii
http://www.network-science.de/ascii/
http://patorjk.com/software/taag/
http://www.degraeve.com/img2txt.php

 

2、两种自定义Banner方式

在自定义Banner之前,先剖析一下源码,源码跟踪解析如下:

  • SpringBoot启动的main方法
public static void main(String[] args) {
		SpringApplication springApplication = new SpringApplication(Application.class);
		//开启Banner打印方式(OFF:关闭,CONSOLE:控制台输出,LOG:日志输出)
		springApplication.setBannerMode(Mode.LOG);
		springApplication.run(args);
	}
  • SpringApplication.printBanner():
private Banner printBanner(ConfigurableEnvironment environment) {
     //是否开启Banner模式
      if (this.bannerMode == Mode.OFF) {
          return null;
      } else {
          ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader : new DefaultResourceLoader((ClassLoader)null);
          SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter((ResourceLoader)resourceLoader, this.banner);
          return this.bannerMode == Mode.LOG ? bannerPrinter.print(environment, this.mainApplicationClass, logger) : bannerPrinter.print(environment, this.mainApplicationClass, System.out);
      }
  }
  • SpringApplicationBannerPrinter.print()
Banner print(Environment environment, Class<?> sourceClass, Log logger) {
	   //调用getBanner()方法
      Banner banner = this.getBanner(environment);
      try {
          logger.info(this.createStringFromBanner(banner, environment, sourceClass));
      } catch (UnsupportedEncodingException var6) {
          logger.warn("Failed to create String for banner", var6);
      }
      return new SpringApplicationBannerPrinter.PrintedBanner(banner, sourceClass);
  }
  • SpringApplicationBannerPrinter.getBanner()
private Banner getBanner(Environment environment) {
  SpringApplicationBannerPrinter.Banners banners = new SpringApplicationBannerPrinter.Banners();
  //先获取image类型的banner
  banners.addIfNotNull(this.getImageBanner(environment));
  //在获取text类型的banner
  banners.addIfNotNull(this.getTextBanner(environment));
  if (banners.hasAtLeastOneBanner()) {
      // 如果至少有一个,则返回
      // Banners 也实现了 Banner 接口,运用了组合模式,实际上可同时打印图片和文本 banner。
      return banners;
  } else {
       // 返回自定义的banner(this.fallbackBanner) 或者 springboot默认的banner(DEFAULT_BANNER)
       // 默认的banner类:SpringBootBanner。
       // 自定义的banner:需要我们仿照SpringBootBanner去自定义一个类
       
       //this.fallbackBanner: 表示自定义的banner,此参数可在springboot启动类的main方法中设置,后续会介绍
       
       //   public static void main(String[] args) {
       //        SpringApplication springApplication = new SpringApplication(Application.class);
       //        springApplication.setBanner(new MyBanner());//自定义的banner
       //        springApplication.run(args);
       //   }
      
        return this.fallbackBanner != null ? this.fallbackBanner : DEFAULT_BANNER;
  }
}

解释:banner的获取方式有两种,先获取image类型的banner,然后获取text类型的banner,如果至少有一个,则执行该banner,如果没有,返回自定义的banner,如果自定义也没有,则返回默认

那么上述源码中是如何获取image类型和Text类型的banner呢?
SpringApplicationBannerPrinter.getImageBanner()
SpringApplicationBannerPrinter.getTextBanner()

//获取Text类型的banner
private Banner getTextBanner(Environment environment) {
  //先从spring.banner.location路径中去取,如果没有,默认banner.txt
  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 var5) {}
  return null;
}

//获取image类型的banner
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;
  } else {
      String[] var3 = IMAGE_EXTENSION;
      int var4 = var3.length;
      for(int var5 = 0; var5 < var4; ++var5) {
          String ext = var3[var5];
          Resource resource = this.resourceLoader.getResource("banner." + ext);
          if (resource.exists()) {
              return new ImageBanner(resource);
          }
      }
      return null;
  }
}

基于图片的 banner

  • 可通过配置参数 spring.banner.image.location 来指定
  • 可将名为 “banner.jpg” (哪几种类型取决于ext常量的定义) 的文件放在classpath 目录(src/main/resources)

基于文件的 banner

  • 可通过配置参数 spring.banner.location 来指定
  • 可将名为 “banner.txt” 的文件放在 classpath 目录(src/main/resources)

源码分析完毕,那么如何去自定义呢?

第一种:配置方式(直接在properties或yml文件中进行配置)
即配置 spring.banner.image.location 和 spring.banner.location路径
或者
将 “图片” 和 “banner.txt” 放在classpath 目录中

spring.banner.location=classpath:banner1.png
spring.banner.image.margin=2
spring.banner.image.height=76
spring.banner.charset=UTF-8
spring.banner.image.invert=false
spring.banner.image.location=banner1.png
spring.main.banner-mode=console
spring.main.show-banner=true

第二种:自定义banner

import org.springframework.boot.Banner;
import org.springframework.boot.ansi.AnsiColor;
import org.springframework.boot.ansi.AnsiOutput;
import org.springframework.boot.ansi.AnsiStyle;
import org.springframework.core.env.Environment;
import java.io.PrintStream;
/** 自定义banner类
* @author hb
* @date 2021-09-09 10:39
*/
public class MyBanner implements Banner {

  private static final String[] BANNER = new String[]{"", "  .   ____          _            __ _ _", " /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\", "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\", " \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )", "  '  |____| .__|_| |_|_| |_\\__, | / / / /", " =========|_|==============|___/=/_/_/_/"};

  public MyBanner() {
  }

  @Override
  public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
      String[] bannerArray = BANNER;
      int bannerLength = bannerArray.length;
      for(int i = 0; i < bannerLength; ++i) {
          String line = bannerArray[i];
          out.println(line);
      }
      out.println(AnsiOutput.toString(new Object[]{AnsiColor.GREEN, " :: Spring Boot :: ", AnsiColor.DEFAULT,  AnsiStyle.FAINT}));
      out.println();
  }
}

如何使用自定义Banner?
springboot启动类中添加自定义banner

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
 public static void main(String[] args) {
    SpringApplication springApplication = new SpringApplication(Application.class);
    //添加自定义banner
    springApplication.setBanner(new MyBanner());
    springApplication.run(args);
 }
}

如果不想打印banner,可以在启动类的main中,设置 springApplication.setBannerMode(Banner.Mode.OFF);
或者
通过参数配置spring.main.banner-mode=off来关闭banner的打印

 

3、控制banner样式

Spring提供了三个枚举类来设定字符的颜色,分别是:

AnsiColor: 用来设定字符的前景色
AnsiBackground: 用来设定字符的背景色
AnsiStyle: 用来控制加粗、斜体、下划线等等。

 

4、显示应用信息

除了上面的指定样式之外,还可以显示一些与应用相关的版本信息:

${application.version}   与 MANIFEST.MF文件中相同的版本号,比如1.5.4.RELEASE
${application.formatted-version}   格式化过的版本号就是加个v然后用括号包起来,比如(v1.5.4.RELEASE)
${application.title} 
${spring-boot.version} Spring Boot的版本
${spring-boot.formatted-version} 格式化过的版本

关于SpringBoot之自定义Banner详解的文章就介绍至此,更多相关SpringBoot之自定义Banner内容请搜索编程宝库以前的文章,希望大家多多支持编程宝库

 SpringBoot JMX的基本使用1. 声明当前内容主要为学习和使用SpringBoot注册JMX的操作,主要方便管理需要的类当前内容来源:SpringBoot官方文档主要内容为: ...