Spring Boot-custom banner pattern

I am Chenpi, an ITer in Coding on the Internet, search for " JavaLib of Chenpi " on WeChat, read the latest article for the first time, reply [ data ], you can get my carefully compiled technical information, e-books, first-line interview information and excellent. Resume template.

Article Directory

Preface


When we start the Spring Boot project, the Springlogo and version information will be printed on the console by default , as follows:


Insert picture description here



This is the Banner printing function of Spring Boot. In fact, we can customize the printing banner, or disable and enable the printing banner function. In real projects, we generally don't customize the banner pattern. It is actually a pattern or text that is printed when the project starts, which has no practical meaning. It is recommended to play with this easter egg in your own personal project. By the way, simply understand its internal implementation principle.

Insert picture description here

For example, after customizing a banner, the project startup console prints as follows:


Insert picture description here
Insert picture description here


Realization principle


Spring Boot has an interface org.springframework.boot.Bannerdedicated to realize this operation. To custom print banner, as long as a custom class that implements this interface, rewriting printBannermethod for printing can be. When Springboot start of the project, we will create the implementation class object and call the object's printBannermethods.

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


Default Banner implementation class


Springboot already has several built-in Banner implementation classes. When Springboot starts, it will select different Banner implementation classes to print banner information according to the conditions. Mainly ImageBanner, ResourceBanner, SpringBootBannerthree implementation class.

  1. When the project starts, to determine whether certain conditions are met (if there is banner file in the project), established the creation ImageBannerand ResourceBannerclass objects, and use them to print banner.
  2. If it is not true, check whether there is our custom Banner implementation class fallbackBanner, if it exists, use it to print the banner pattern.
  3. Otherwise, use the default SpringBootBannerimplementation class to print the banner, that is, we often see Springa pattern.
// 获取可用的 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.ImageBannerThe class is dedicated to loading and printing image banners. It checks the configuration files application.proeprtiesif there is configured spring.banner.image.locationvalue of the variable, this value can be used to specify the images to load, if present building ImageBanner object. If no variables, it will also check Classpathwhether there is to bannerbegin with, to .gif, .jpg, .pngat the end of the picture file, if there will be constructed ImageBanner object.

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.ResourceBannerThe class is dedicated to loading and printing character banners. It checks the configuration files application.proeprtiesif there is configured spring.banner.locationvalue of the variable, this value can be used to specify the file to be loaded, if present building ResourceBanner object. If no variables, it will also check for the presence of the resource path banner.txtfile, if there will be constructed ResourceBanner object.

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;
	}
}

If you want to customize the banner, we generally create resources in the resource directory of the project banner.txtfile, and then fill in the text we want to print on the inside. For example, I filled in banner.txt file Chen Pi, and then start the project.

Insert picture description here


Insert picture description here


SpringBootBanner

If the project is not set from banner above two definitions (ImageBanner and ResourceBanner), by default, will be used to print banner SpringBootBanner implementation class, that is, when we started the project in the console Springboot see print Springpattern. The source code is as follows:

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();
	}

}


Implement the Banner class

As mentioned earlier, we can implement the Banner class, rewrite the printing method, and implement custom banner printing functions.

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 create a custom implementation class objects, set to SpringApplicationbanner Properties class object, the final value of this property will be assigned to the SpringApplicationBannerPrinterobject's fallbackBannerproperties, interested can start the next debug tracing.

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

At the beginning of the article, you will find that the Buddha image is emerald green. In fact, Springboot supports us to modify the color of the banner, font italic, bold and other styles. SpringBoot provides us with three enumeration classes to set these styles.

  1. ANSIColor : foreground color character set; see org.springframework.boot.ansi.AnsiColorenumeration class.
  2. AnsiBackground : setting the background color of the character; reference org.springframework.boot.ansi.AnsiBackgroundenumeration class.
  3. AnsiStyle : character set of bold, italic, underline, and so on; reference org.springframework.boot.ansi.AnsiStyleenumeration class.

Moreover, some global variables can also be referenced in the banner.txt file, for example:

  1. ${spring-boot.version} : Spring Boot version number;
  2. ${spring-boot.formatted-version} : Formatted Spring Boot version number information.
  3. ${application.version} : the version number in the MANIFEST.MF file;
  4. ${application.formatted-version} : the version number information in the formatted MANIFEST.MF file;

Not only that, we also can be referenced in the configuration file application.propertiesvariable definition, for example, defines the following variables in the configuration file:

application.auth=chenpi

The content of the defined banner.txt file is as follows:

${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}

Start the project, the banner that will be printed on the console is as follows:


Insert picture description here



An enumeration class is defined in the Banner interface. This enumeration defines the possible enumeration values ​​for configuring Banner, as follows:

@FunctionalInterface
public interface Banner {

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

So we can choose to close the banner, print the banner to the console or log file, as follows:

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

You can also set this value in the configuration file, as follows

spring.main.banner-mode=off

If the settings of the banner switch are configured in both the startup class and the configuration file, the banner switch set in the configuration file will take precedence over the switch set in the startup class.



Some people may ask how the Buddha's pattern was edited. In fact, there are many tools on the Internet that can customize ASCII characters and patterns according to the content or pictures we input. The recommended URL is as follows: