【Spring Boot 源码学习】自定义 Banner 信息打印

Spring Boot 源码学习系列

在这里插入图片描述

自定义 Banner 信息打印

  • 引言
  • 往期内容
  • 主要内容
    • 1. ResourceBanner 打印
      • 1.1 添加默认的 banner.txt 资源文件
      • 1.2 指定任意路径的资源文件
      • 1.3 添加自定义的信息
    • 2. ImageBanner 打印
      • 2.1 添加默认的图像资源文件
      • 2.2 指定任意路径的图像资源文件
      • 2.3 添加自定义的图像显示信息
        • 2.3.1 添加 Banner 图像宽度属性
        • 2.3.2 添加 Banner 图像高度属性
        • 2.3.3 添加 Banner 图像外边距属性
        • 2.3.4 添加 Banner 图像是否反转图片颜色的属性
        • 2.3.5 添加 Banner 图像位深度的属性
        • 2.3.6 添加 Banner 图像像素模式的属性
    • 3. Banners 打印
    • 4. 自定义 Banner 接口实现
  • 总结

引言

上篇博文,Huazie 带大家了解了完整的 Banner 信息打印流程。相信大家都跃跃一试了,那么本篇就以这些基础的知识,来自定义 Banner 信息打印。

注意: 以下涉及 Spring Boot 源码 均来自版本 2.7.9,其他版本有所出入,可自行查看源码。

在这里插入图片描述

往期内容

在开始本篇的内容介绍之前,我们先来看看往期的系列文章【有需要的朋友,欢迎关注系列专栏】:

Spring Boot 源码学习
Spring Boot 项目介绍
Spring Boot 核心运行原理介绍
【Spring Boot 源码学习】@EnableAutoConfiguration 注解
【Spring Boot 源码学习】@SpringBootApplication 注解
【Spring Boot 源码学习】走近 AutoConfigurationImportSelector
【Spring Boot 源码学习】自动装配流程源码解析(上)
【Spring Boot 源码学习】自动装配流程源码解析(下)
【Spring Boot 源码学习】深入 FilteringSpringBootCondition
【Spring Boot 源码学习】OnClassCondition 详解
【Spring Boot 源码学习】OnBeanCondition 详解
【Spring Boot 源码学习】OnWebApplicationCondition 详解
【Spring Boot 源码学习】@Conditional 条件注解
【Spring Boot 源码学习】HttpEncodingAutoConfiguration 详解
【Spring Boot 源码学习】RedisAutoConfiguration 详解
【Spring Boot 源码学习】JedisConnectionConfiguration 详解
【Spring Boot 源码学习】初识 SpringApplication
【Spring Boot 源码学习】Banner 信息打印流程

主要内容

1. ResourceBanner 打印

通过 SpringApplicationBannerPrinter##getTextBanner 方法的源码了解,我们现在可以进行如下的操作:

1.1 添加默认的 banner.txt 资源文件

当没有配置 spring.banner.location 属性,Spring Boot 默认就会加载资源根目录的 banner.txt 文件,如果存在该资源文件,则会使用 ResourceBanner 打印 Banner 信息。

下面我们在新建的 demo 项目的资源根目录添加名为 banner.txt 的资源文件,如下图所示:

【Spring Boot 源码学习】自定义 Banner 信息打印_第1张图片

然后,直接运行我们的 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第2张图片

1.2 指定任意路径的资源文件

现在我们把上面的 banner.txt 移到资源根目录新建的 banner 目录里,并更名为 mybanner.txt,如下图所示:

【Spring Boot 源码学习】自定义 Banner 信息打印_第3张图片

接着,在 application.properties 中配置如下:

# Banner 资源文件路径
spring.banner.location=classpath:banner/mybanner.txt

然后,还是直接运行我们的 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第4张图片

1.3 添加自定义的信息

查看 ResourceBanner 的源码,我们可以看到如下的代码:

【Spring Boot 源码学习】自定义 Banner 信息打印_第5张图片
【Spring Boot 源码学习】自定义 Banner 信息打印_第6张图片
【Spring Boot 源码学习】自定义 Banner 信息打印_第7张图片

这里就不得不提 PropertyResolver,它是 Spring 框架中的一个组件,主要用于解析各种属性源的属性值。它能够处理多种类型的底层源,包括properties 文件、yaml 文件,甚至是一些 nosql 数据库【因为这些数据源同样采用 key-value 形式存储数据】。

查看 PropertyResolverAPI 中,我可以看到它定义了一系列读取、解析和判断是否包含指定属性的方法。此外,它还支持以 ${propertyName:defaultValue} 格式的属性占位符,替换为实际的值的功能,这在动态配置中非常有用。

接下来,我们在 application.properties 中配置如下:

【Spring Boot 源码学习】自定义 Banner 信息打印_第8张图片

然后,我们在 banner.txt 中可以添加如下属性占位符:

【Spring Boot 源码学习】自定义 Banner 信息打印_第9张图片

最后,运行我们的 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第10张图片

2. ImageBanner 打印

通过 SpringApplicationBannerPrinter##getImageBanner 方法的源码了解,我们现在可以进行如下的操作:

2.1 添加默认的图像资源文件

当没有配置 spring.banner.image.location 属性,Spring Boot 默认就会加载资源根目录的 banner.gifbanner.jpgbanner.png 等文件,如果存在其中某个资源文件,则会使用 ImageBanner 打印 Banner 信息。

下面我们在新建的 demo 项目的资源根目录添加名为 banner.gif 的资源文件,如下图所示:

【Spring Boot 源码学习】自定义 Banner 信息打印_第11张图片

然后,同样运行我们的 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第12张图片

换成另外两个 banner.jpgbanner.png 也是能够加载的,如下:
【Spring Boot 源码学习】自定义 Banner 信息打印_第13张图片
【Spring Boot 源码学习】自定义 Banner 信息打印_第14张图片

默认 Banner 图像资源的加载逻辑:

  • 存在 banner.gif,则只加载 banner.gif
  • 不存在 banner.gif,存在 banner.jpg,则只加载 banner.jpg
  • 不存在 banner.gif,也不存在 banner.jpg,则加载 banner.png

2.2 指定任意路径的图像资源文件

现在我们把上面的 banner.png 移到资源根目录新建的 banner 目录里,并更名为 mybanner.png,如下图所示:

【Spring Boot 源码学习】自定义 Banner 信息打印_第15张图片

接着,在 application.properties 中配置如下:

# Banner 图像资源文件路径
spring.banner.image.location=classpath:banner/mybanner.png

然后,我们运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第16张图片

2.3 添加自定义的图像显示信息

查看 ImageBanner 的源码,我们可以看到如下的代码:

【Spring Boot 源码学习】自定义 Banner 信息打印_第17张图片
【Spring Boot 源码学习】自定义 Banner 信息打印_第18张图片
在这里插入图片描述

从上述源码,我们看到 ImageBanner 里面可以自定义一些图像的显示属性,比如:

  • spring.banner.image.width :设置 banner 图像的宽度,默认为 76 像素

  • spring.banner.image.height :设置 banner 图像的高度,默认按照宽度计算缩放比例,重新计算新图像的高度。
    【Spring Boot 源码学习】自定义 Banner 信息打印_第19张图片

  • spring.banner.image.margin :设置 banner 图像的外边距,默认为 2 像素

  • spring.banner.image.invert :设置是否反转图片的颜色。如果设置为 true,则颜色会被反转

  • spring.banner.image.bitdepth :设置图片的位深度,默认 4 位深度,还支持 8 位深度。位深度决定了图片的颜色精度,例如8位深度表示每个像素有256种颜色,不过大多数情况下,对于 Banner 图像输出到控制台,看起来基本没啥区别。

  • spring.banner.image.pixelmode :设置图片的的像素模式,有如下两个枚举值:

    • TEXT :文本模式,适用于需要清晰、简洁的图像效果的情况。
      【Spring Boot 源码学习】自定义 Banner 信息打印_第20张图片
    • BLOCK :块模式,适用于需要强调图像的某些部分或突出显示特定区域的情况。
      【Spring Boot 源码学习】自定义 Banner 信息打印_第21张图片

下面我们就来添加这些属性,来看看效果:

2.3.1 添加 Banner 图像宽度属性
spring.banner.image.width=50

运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第22张图片

2.3.2 添加 Banner 图像高度属性
spring.banner.image.height=20

依旧运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第23张图片

2.3.3 添加 Banner 图像外边距属性
spring.banner.image.margin=5

同样运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第24张图片

2.3.4 添加 Banner 图像是否反转图片颜色的属性
spring.banner.image.invert=true

继续运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第25张图片

2.3.5 添加 Banner 图像位深度的属性
spring.banner.image.bitdepth=8

然后运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第26张图片
我们发现上述好像设置了该属性,展示出来的图像并没有啥差异,事实上在也的确如此,可能我们的图像比较简单。

2.3.6 添加 Banner 图像像素模式的属性
spring.banner.image.pixelmode=block

运行 DemoApplication 入口类,可见如下运行截图:
【Spring Boot 源码学习】自定义 Banner 信息打印_第27张图片
【Spring Boot 源码学习】自定义 Banner 信息打印_第28张图片

3. Banners 打印

BannersSpringApplicationBannerPrinter 的私有静态内部类,它也实现了 Banner 接口,添加多个不同的 Banner 实现。在 SpringApplicationBannerPrinter##getBanner 方法中就能看到,新建 Banners 实例,并往其中添加了 ImageBannerResourceBanner

按照 Banners 的打印顺序,先添加进去的,先打印。

【Spring Boot 源码学习】自定义 Banner 信息打印_第29张图片
【Spring Boot 源码学习】自定义 Banner 信息打印_第30张图片

我们看看 ImageBannerResourceBanner 同时生效的场景:

【Spring Boot 源码学习】自定义 Banner 信息打印_第31张图片

运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第32张图片

4. 自定义 Banner 接口实现

通过阅读 SpringApplicationBannerPrinter 的源码,我们知道如果 Banners 中没有 ResourceBanner 或者 ImageBanner 中的任何一个,就会判断自身的 fallbackBanner 变量是否存在,存在则直接返回。而该 fallbackBanner 变量实际上是 SpringApplication 中的 banner 变量。

【Spring Boot 源码学习】自定义 Banner 信息打印_第33张图片
【Spring Boot 源码学习】自定义 Banner 信息打印_第34张图片
在这里插入图片描述

而我们查看 SpringApplication 的源码,可以看到如下方法:

【Spring Boot 源码学习】自定义 Banner 信息打印_第35张图片

下面就需要我们来自定义 Banner 接口的实现:

/**
 * 自定义 Banner 接口实现
 *
 * @author huazie
 * @version 2.0.0
 * @since 2.0.0
 */
public class CustomBanner implements Banner {

    @Override
    public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
        String author = environment.getProperty("author");

        out.println(" _   _                 _      ");
        out.println("| | | |_   _  __ _ ___(_) ___ ");
        out.println("| |_| | | | |/ _` |_  / |/ _ \\");
        out.println("|  _  | |_| | (_| |/ /| |  __/");
        out.println("|_| |_|\\__,_|\\__,_/___|_|\\___|");
        out.println("                              ");
        out.println(" 作者: " + author);
        out.println();
    }
}

接下来,修改入口类 DemoApplication,如下:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(DemoApplication.class);
        springApplication.setBanner(new CustomBanner());
        springApplication.run(args);
    }
}

最后运行 DemoApplication 入口类,可见如下运行截图:

【Spring Boot 源码学习】自定义 Banner 信息打印_第36张图片

总结

本篇 Huazie 带大家自定义 Banner 信息打印,再次加深了对 Banner 信息打印流程的理解。当然,这只是 Spring Boot 启动过程中的一个小插曲,后续的博文我们将继续深入讲解 SpringApplication 的其他内容,敬请期待!!!

你可能感兴趣的:(开发框架-Spring,Boot,spring,boot,源码学习,自定义Banner信息打印)