spring boot 在应用程序启动时会打印出 banner 信息。spring 是可扩展的,banner 也是可以自由定制的,比如打印出个人的网站信息等,甚至是图片,本文就来探讨一下这个问题。
注:本文基于 spring boot 版本 1.5.12.RELEASE。

源码分析

默认,spring boot 会打印出如下内容:

图片描述

ASCII Art,显目的单词 spring,附带 spring boot 版本信息。

Spring boot 是如何处理的呢?

带着问题,我们来分析源码,定位到 SpringApplication 类的 printBanner 方法,源码如下:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611161302433-1666345226.png" alt="">

代码比较简单,我们看到打印 banner 的操作委托给了 SpringApplicationBannerPrinter 类,再来看它的源码:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611161333167-660387688.png" alt="">

上述代码,我们稍加解释:

  • 打印 banner 前自然先要获取 Banner 对象
  • 打印 banner 的操作实际上由 Banner 本身来完成
  • 打印到日志是先由 Banner 将内容输出到内存中拿到打印内容后再委托给 logger 来打印
  • 打印到标准输出是将 System.out 作为参数传入 Banner 对象作为输出目的地

我们再来看看获取 banner 这段代码:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611161644472-1075166223.png" alt="">

这段代码大致逻辑:

  • 创建一个 Banners 对象,可组合多个 banner
  • 尝试获取基于图片的 banner
  • 尝试获取基于文本的 banner
  • 前两步操作完成后,如果拿到至少一个 banner 则返回 Banners 对象
  • 前两步操作后都没有获取到 banner,返回自定义的 banner (如果存在)
  • 若自定义 banner 也不存在,返回默认的
    注: Banners 也实现了 Banner 接口,运用了组合模式,实际上可同时打印图片和文本 banner。
    以上内容就是打印 banner 的大体逻辑,我们再来看一看细节。

基于配置的方式自定义 Banner

看看基于图片和文本两种形式的 banner 获取源码:
注:为了方便读者阅读,笔者把 spring 定义的常量替换成了原字符串本身

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611161721414-769898078.png" alt="">

通过这段代码,我们可得出结论:

基于图片的 banner

  • 可通过配置参数 banner.image.location 来指定
  • 可将名为 banner.jpg (gif|png) 的文件放在 classpath 目录

基于文件的 banner

  • 可通过配置参数 banner.location 来指定
  • 可将名为 banner.txt 的文件放在 classpath 目录

居然可以打印图片,是不是很好玩,那么我们就来试一把。

我们在 classpath 目录下存放一个名为 banner.jpg 的图片,图片如下:

图片描述

同时也放一个名为 banner.txt 的文件,内容为:

Hello, Spring boot<br>

运行程序,最终我们看到如下效果:

图片描述

图片的打印效果是 ASCII 字符画,太好玩了。ASCII 字符画后面紧接着文本文件的内容。

至此,我相信你已经学会如何自定义一个好玩的 banner 了,但我们的文章还要继续。刚才说的两种方式是基于配置的形式,接下来我们来说一下如何基于编程的方式来实现。

基于编程的方式自定义 Banner

既然要通过编程的方式实现,那自然要实现 Banner 接口了,源码如下:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611161924467-1021731627.png" alt="">

代码也很简单, 只定义了一个 printBanner 方法。

同时还定义了打印模式:

  • 禁用(不打印)
  • 控制台(标准输出)
  • 日志

前面有提到 Banners ,我们也看一下源码:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611161953008-1913327056.png" alt="">

Banners 也实现了 Banner 接口,内置一个 Banner 集合,运用了组合模式。

还记得前面提到的 spring 默认 Banner 么,我们来看一下源码:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611162024570-1005284020.png" alt="">

是不是很好玩,内置了 ASCII 字符画。

既然我们要编写自己的 Banner,那么很简单,照葫芦画瓢。

看一下笔者的简单实现:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611162045387-2056669276.png" alt="">

Banner 实现好了,我们怎么使它生效呢。很简单,我们看一下启动类:

<img src="https://images2018.cnblogs.com/blog/1413382/201806/1413382-20180611162115490-1852650821.png" alt="">

我们再看一下打印效果,如下图:

图片描述

看到这里,你是不是很想自己实现一个有趣的 banner 呢?

小结

本文中我们主要讲了如何自定义 Banner,我们既可以通过配置的方式来指定 banner 文件又可通过编程的方式来实现。