6.SpringBoot学习(六)——Spring Boot Banner自定义

1.简介

1.1 概述

The banner that is printed on start up can be changed by adding a banner.txt file to your classpath or by setting the spring.banner.location property to the location of such a file. If the file has an encoding other than UTF-8, you can set spring.banner.charset. In addition to a text file, you can also add a banner.gif, banner.jpg, or banner.png image file to your classpath or set the spring.banner.image.location property. Images are converted into an ASCII art representation and printed above any text banner.

banner 是在启动时打印的内容,可以通过在 classpath 下添加 “ banner.txt” 文件或 设置“ spring.banner.location” 属性值来改变 banner 的内容。如果文件的编码不是UTF-8,则可以通过spring.banner.charset 进行设置。除了文本文件之外,您还可以在 classpath 下添加 banner.gifbanner.jpgbanner.png 图像文件或设置 spring.banner.image.location 属性。图片将被转换为 ASCII 的形式进行展现并在文本内容之前打印。

1.2 特点

banner.txt 可以包含如下内容

Variable Description
${application.version} The version number of your application, as declared in MANIFEST.MF. For example, Implementation-Version: 1.0 is printed as 1.0.
${application.formatted-version} The version number of your application, as declared in MANIFEST.MF and formatted for display (surrounded with brackets and prefixed with v). For example (v1.0).
${spring-boot.version} The Spring Boot version that you are using. For example 2.2.8.RELEASE.
${spring-boot.formatted-version} The Spring Boot version that you are using, formatted for display (surrounded with brackets and prefixed with v). For example (v2.2.8.RELEASE).
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}) Where NAME is the name of an ANSI escape code. See AnsiPropertySource for details.
${application.title} The title of your application, as declared in MANIFEST.MF. For example Implementation-Title: MyApp is printed as MyApp.

The SpringApplication.setBanner(…) method can be used if you want to generate a banner programmatically. Use the org.springframework.boot.Banner interface and implement your own printBanner() method.

You can also use the spring.main.banner-mode property to determine if the banner has to be printed on System.out (console), sent to the configured logger (log), or not produced at all (off).

2.演示环境

  1. JDK 1.8.0_201
  2. Spring Boot 2.2.0.RELEASE、Spring Cloud Hoxton.RELEASE
  3. 构建工具(apache maven 3.6.3)
  4. 开发工具(IntelliJ IDEA )

3.演示代码

3.1 代码说明

自定义 banner.txt,在项目启动时打印自定义 banner

3.2 代码结构

image-20200713193628565

3.3 maven 依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3.4 配置文件

application.properties

application.version=0.0.1-SNAPSHOT
application.formatted-version=0.0.1
application.title=spring-boot-banner

banner.txt

${application.version}
${application.formatted-version}
${application.title}
${AnsiColor.BRIGHT_GREEN}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
${AnsiColor.BRIGHT_CYAN}$$       _________  __  __/ / /_  ____ _/ / /___ _____/ /    $$
${AnsiColor.BRIGHT_CYAN}$$      / ___/ __ \/ / / / / __ \/ __ `/ / / __ `/ __  /     $$
${AnsiColor.BRIGHT_CYAN}$$     (__  ) /_/ / /_/ / / /_/ / /_/ / / / /_/ / /_/ /      $$
${AnsiColor.BRIGHT_CYAN}$$    /____/\____/\__,_/_/_.___/\__,_/_/_/\__,_/\__,_/       $$
${AnsiColor.BRIGHT_GREEN}$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
               ${AnsiColor.BRIGHT_RED}Spring Boot: ${spring-boot.formatted-version}

3.6 git 地址

spring-boot/spring-boot-05-basis/spring-boot-banner

4.测试

启动 SpringBootBannerApplication.main 方法,打印出 banner.txt 中内容

image-20200713193939809

5.源码分析

5.1 banner 如何打印的?

banner 是如何打印的呢?

在 spring boot 项目启动时,调用 run 方法,最终会调用到 printBanner 方法

public ConfigurableApplicationContext run(String... args) {
    // ...
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        configureIgnoreBeanInfo(environment);
        // 打印 banner
        Banner printedBanner = printBanner(environment);
        // ...
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, listeners);
        throw new IllegalStateException(ex);
    }

    //...
    return context;
}

它的实现如下

private Banner printBanner(ConfigurableEnvironment environment) {
    // 如果关闭 banner,直接返回
    if (this.bannerMode == Banner.Mode.OFF) {
        return null;
    }
    // 默认 resourceLoader=null,使用 DefaultResourceLoader
    ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader
        : new DefaultResourceLoader(getClassLoader());
    SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);
    // bannerMode 有3中取值,OFF、CONSOLE、LOG,这里默认为 CONSOLE
    if (this.bannerMode == Mode.LOG) {
        return bannerPrinter.print(environment, this.mainApplicationClass, logger);
    }
    // 打印 banner
    return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}

bannerPrinter.print

Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
    // 获取 banner,先获获取图片类型,再获取文本类型,都没有则答应 Spring Boot
    Banner banner = getBanner(environment);
    // 如果有多种类型,循环打印;按照添加顺序,先图片再文本
    banner.printBanner(environment, sourceClass, out);
    return new PrintedBanner(banner, sourceClass);
}

banner.printBanner

@Override
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
    for (Banner banner : this.banners) {
        banner.printBanner(environment, sourceClass, out);
    }
}

这里看下文本打印,ResourceBanner.printBanner

@Override
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
    try {
        // 获取编码格式
        String banner = StreamUtils.copyToString(this.resource.getInputStream(),
                                                 environment.getProperty("spring.banner.charset", Charset.class, StandardCharsets.UTF_8));
		// 处理 banner 文件中属性值
        for (PropertyResolver resolver : getPropertyResolvers(environment, sourceClass)) {
            banner = resolver.resolvePlaceholders(banner);
        }
        // 使用 java bio 进行打印
        out.println(banner);
    }
    catch (Exception ex) {
        logger.warn(
            "Banner not printable: " + this.resource + " (" + ex.getClass() + ": '" + ex.getMessage() + "')",
            ex);
    }
}

6.参考

  1. 官方文档-Spring Boot Features/Banner
posted @ 2020-07-13 19:57  Soulballad  阅读(265)  评论(0编辑  收藏  举报