Springboot-banner图-定制化

Springboot启动后打印的图形是什么?

相信有部分猿宝宝们看到Springboot启动后打印出的图形文字特别感兴趣

Springboot-banner图-定制化_第1张图片

这种类图形化称为banner,也就是横幅,像我们引入一些其他厂商的框架比如mybatis也会打印出banner

基于Springboot制作Banner

快速制作

其实基于Springboot实现起来特别简单:

在resource下建一个banner.txt文件即可

在这里插入图片描述

我就直接输入一个笔名吧

POWER-J

启动下项目看看效果

在这里插入图片描述

看到了没,Spring被我的POWER-J替代了,不过有的猿宝宝会说,你这啥呀,也不是图形化的啊

别急,有现成的在线工具:

图片转图形文字
文字转图形文字
文字转图形文字2

Springboot-banner图-定制化_第2张图片

作者随便选了个样式,来启动看下效果

Springboot-banner图-定制化_第3张图片

Springboot打印banner原理

作者通过查看源码,并debug调试发现,SpringApplication在启动run方法时,会调用一个printBanner方法

private Banner printBanner(ConfigurableEnvironment environment) {
   if (this.bannerMode == Banner.Mode.OFF) {
      return null;
   }
   ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader
         : new DefaultResourceLoader(null);
   SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);
   if (this.bannerMode == Mode.LOG) {
      return bannerPrinter.print(environment, this.mainApplicationClass, logger);
   }
   return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}

其中SpringApplicationBannerPrinter就是Springboot打印banner的关键

先不管逻辑细节,我们主要看看banner.txt是如何加载的?如果没有banner.txt会怎么样?

直接来看SpringApplicationBannerPrinter的print方法

Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
   Banner banner = getBanner(environment);
   banner.printBanner(environment, sourceClass, out);
   return new PrintedBanner(banner, sourceClass);
}

流程很简单:1、获取Banner对象;2、打印banner;3、返回一个Banner的子包装类PrintedBanner对象

那具体针对获取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;
   }
   return DEFAULT_BANNER;
}
  1. Banners是内部封装了一个List.Banner的内部类,其能力是可以包装多个Banner并依次进行打印
  2. 先找有没有图片banner
  3. 再找有没有文本banner
  4. 如果至少有一个那就返回banners,如果一个都没有就返回默认的banner,这个DEFAULT_BANNER就是SpringBootBanner,用来打印Spring的banner

Banner定制化

那作者为什么要看源码呢?上面的用法其实基本满足大家使用了,直接新增一个banner.txt即可。

其实通过官方文档和源码,能让你更加了解Springboot加载banner的机制

banner.txt复杂配置

Springboot-banner图-定制化_第4张图片

Springboot为我们提供了可以在banner.txt中配置的变量

关于application.version和application.formatted-version一般是在MANIFEST中定义的,不过你不像用MANIFEST也可以直接在配置文件定义,这种用法就没那么”官方“,但是你可以随便定义属性随便用

比如我在banner.txt中增加了如下内容:

${AnsiColor.GREEN}SpringBoot-Version:${spring-boot.version}
${AnsiColor.YELLOW}PowerJ-Version:${application.version}
${AnsiColor.DEFAULT}

打印结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M5fIRhF5-1655785223429)(C:\Users\Heyunqiu\AppData\Roaming\Typora\typora-user-images\image-20220621111540415.png)]

自定义Banner类

官方文档也说明了如何通过实现Banner类来达到自定义

Springboot-banner图-定制化_第5张图片

它让我们自定义一个Banner类来实现Banner接口,并实现pringBanner()方法,并且声明成名为springBootBanner的单例bean(这一点要去确认)

增加自定义类

public class PowerJBanner implements Banner {
    @Override
    public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
        out.println("powerJ");
    }
}

修改启动类

@SpringBootApplication
public class PowerjSpringBootBannerApplication {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(PowerjSpringBootBannerApplication.class);
        application.setBanner(new PowerJBanner());
        application.run(args);
    }
}

启动查看下效果:

结果发现,打印出的banner还是之前banner.txt里的内容。为什么?

还记得上面源码部分getBanner方法么?其中有一个this.fallbackBanner,是在banners.hasAtLeastOneBanner()为false的情况下,才会使用这个banner,而这个banner正是我们在启动类中传进去的自定义banner,说明什么?

说明banner.txt的优先级是高于在启动类中setBanner的。那就先屏蔽banner.txt吧。

重启结果:

在这里插入图片描述

你这啥?还不如直接用banner.txt啊,效果不行啊?

这里作者建议大家去找一些java制作banner的轮子

比如这个
再比如这个

老实说现在的文章你都不知道到底你看的是不是原创,但还是鸣谢下上面两个博客作者吧

我后学也可能会造一个轮子,基于Springboot现有的一些工具类进行扩展,请期待吧!

你可能感兴趣的:(#,SpringBoot实践,spring,boot,java,后端)