暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

中秋国庆番--自定义SpringBoot启动LOGO

糖爸的架构师之路 2021-06-24
1510

写在前面

首先要祝小伙伴们中秋+国庆双节快乐,八天的假期属实有点过瘾。不过我相信肯定还是有很多小伙伴放假期间还依然坚守在一线的开发岗位,为保证我们后台服务的稳定付出着辛苦,在这里向你们致敬,祝加班费拿到手软,不辜负自己的付出和努力

既然是放假,那我们今天就不说枯燥的理论和冗长的源码。来聊点有意思的,相信用过SpringBoot的小伙伴在本地启动服务时都会看到控制台会打印出SpringBoot的LOGO,就像下面这样:

这里我们就可以提出疑问,这个LOGO是在何时,通过什么样的方式打印到控制台的呢?如果我们想要定制属于自己的LOGO,具体要怎么做呢?带着这几个问题,我们来看一下SpingBoot自定义LOGO的方法和原理。


SpringBootApplication.run(Spring...args)

要探究SpringBoot LOGO的打印,我们首先要看一下SpringBoot的启动流程。

要执行SpringBoot启动,就要运行@SpringBootApplication注解所标注的主配置类的

main()方法。这里我们通过Idea的Spring Initializr快速创建出一个空的SpringBoot工程,方便我们进行源码阅读。具体代码如下:

在main()方法中,可以看到SpringApplication调用静态方法run()执行容器启动,跟踪一下代码,最终会调用SpringBootApplication.run(String...args)方法中,这个方法是SpringBoot容器初始化并启动的核心方法。具体方法如下:

在上述代码中其实做了很多事情,例如执行SpringBoot启动时各个时机所涉及到的事件通知、创建Web容器、初始化Spring容器、初始化Spring Bean、构建嵌入式的Tomcat等等。虽然这些动作非常重要,但是这不是我们今天要讨论的重点。我们要讨论的重点是,在执行哪一行代码时,会打印出SpringBoot的LOGO?答案就是我用红框标注的printBanner()方法。如何验证呢?大家可以在这行代码进行断点调试,当这行代码执行完成后,控制台立刻会打印出我们想要看到的SpringBoot的LOGO,所以我们要对这行代码做一下深入的探究。


Banner.Mode

先看一下printBanner()方法的具体实现,具体代码如下:

这里首先会判断一下bannerMode的输出模式,这里就涉及到Banner接口的一个内部枚举类Mode,我们来看一下:

根据源代码中的注释我们可以很明确的知道,LOGO的输出分为三种模式

  • 关闭

  • 通过System.out输出到控制台(默认)

  • 输出到log file中

所以这里printBanner()会判断一下Banner.Mode是否是OFF模式。如果是,则不执行打印方法,我们在控制台中也就看不到打印的LOGO了。那如何修改Banner.Mode呢?具体方法如下:
      public static void main(String[] args) {
    SpringApplication springApplication = new SpringApplication(DemoApplication.class);
    springApplication.setBannerMode(Banner.Mode.OFF);
    springApplication.run(args);
      }
    这样我们在启动的时候,就不会看到LOGO的打印了。感兴趣的小伙伴可以尝试一下输出到log file这种模式。

    获取Banner
    继续分析printBanner()方法,我们可以看到这里面核心的逻辑是调用SpringApplicationPrinter的print()方法,具体代码如下(这里只分析Banner.Mode=CONSULE模式的,LOGGER模式逻辑类似,这里不再赘述):

    这个方法做了两件事情:
    1. 获取Banner接口对应实现类的对象

    2. 执行打印操作

    先看代码
    根据代码我们很容易看出,SpringBoot会加载两种类型的Banner
    • TextBanner

    • ImageBanner


    ImageBanner
      private Banner getImageBanner(Environment environment) {
      // BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";
      // IMAGE_EXTENSION = { "gif", "jpg", "png" };
      // 查看配置文件中是否定义了spring.banner.image.location
      String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
      if (StringUtils.hasLength(location)) {
      // 如果有,则使用location加载资源
      Resource resource = this.resourceLoader.getResource(location);
      // 如果资源存在,则构建一个ImageBanner,如果不存在返回null
      return resource.exists() ? new ImageBanner(resource) : null;
      }
      // 循环查找banner.gif/banner.jpg/banner.png三种格式的banner
      for (String ext : IMAGE_EXTENSION) {
      Resource resource =
      this.resourceLoader.getResource("banner." + ext);
      // 如果存在,则构建ImageBanner,不存在则返回null
      if (resource.exists()) {
      return new ImageBanner(resource);
      }
      }
      return null;
        }

      TextBanner
          private Banner getTextBanner(Environment environment) {
        // BANNER_LOCATION_PROPERTY = "spring.banner.location";
        // DEFAULT_BANNER_LOCATION = "banner.txt";
        // 从配置文件中获取spring.banner.location的值,
        // 如果没有,默认使用banner.txt
        String location = environment.getProperty(
        BANNER_LOCATION_PROPERTY,
        DEFAULT_BANNER_LOCATION);
        // 通过location加载资源
        Resource resource = this.resourceLoader.getResource(location);
        // 如果资源存在,则构建一个ResourceBanner对象,如果不存在,则返回空
        if (resource.exists()) {
        return new ResourceBanner(resource);
        }
        return null;
          }

        如果以上两种Banner都加载不到,则回去加载默认的SpringBootBanner。代码如下:

        这就是我们启动时默认看到的SpringBoot的LOGO。


        执行打印操作

        获取到Banner对象之后就会调用Banner接口的printBanner方法执行打印操作。这里比较简单,我就简单介绍一下。

        针对ResourceBanner,会先将Banner.txt文件转成输入流对象,然后调用System.out输出到控制台。这中间会做一些渲染着色的操作。

        针对ImageBanner,会先根据图片的形状大小使用特殊字符描绘出同比例的长宽高,然后再根据图片的颜色将输出字符进行着色操作并最终输出,也就是说,虽然我们在项目中放了一张图片,但是在打印时,SpringBoot并不会真正将图片渲染到控制台,而是通过字符的方式,大概描绘出所放置的图片的样式。

        最后是SpringBootBanner


        自定义图片和文字LOGO

        通过上面源代码的介绍,我们已经对原理了解的比较清楚。那么接下来定制自己的LOGO就是一件非常简单的事情了。下面我就直接说一下步骤:

        文字LOGO:
        1. 在resources目录下新建banner.txt

        2. 将自定义的图案放到banner.txt中。那图案从哪里来呢?这里介绍一个非常好用的工具网站:http://patorjk.com/software/taag,在网页上可以自由定制你想要的图案(仅支持英文)。例如我输入Sugar,会出来很多风格不同的LOGO。

        直接将这些图案复制到banner.txt中,就可以达到我们想要的效果。


        图片LOGO:

        步骤和文字一样,只不过图片仅仅支持gif、jpg、png三种格式。将图片名称改成banner+后缀 后,直接放到resources目录下即可。

        例如下面:

        这里小伙伴们可以猜测一下,这个图标是那家公司的LOGO?(友情提示:这公司的拳头产品,中国大陆用不了)对答案感兴趣的小伙伴可以后台私信我。
        以上就是SpringBoot自定义LOGO的全部内容。步骤虽然非常简单,但是我们对源码的深入探究有助于我们更好的运用和拓展。最后再次祝小伙伴们双节快乐。假期之余,别忘记撸撸代码热热身哟~,随时准备996->ICU
        文章转载自糖爸的架构师之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论