自定义Springboot启动Banner

简介: 自定义Springboot启动Banner

相信使用过Springboot的朋友们肯定对于这个图不陌生,这就是Springboot服务启动时候的默认的启动Banner。

作为爱倒腾的程序员,肯定不满足一成不变的这个图,自定义是必须的,例如打印个“LOVE”,或者把你女朋友的照片打印出来。于是乎,就要弄懂Banner打印的原理以及如何自定义打印的Banner图。

一、自定义Banner

先来看看效果打印一个"I LOVE JAVA"的ASCII图形的效果,如下图

在Springboot中打印实现这样子的一个效果非常简单,只需要在类路径下(Springboot的resources文件夹下)放置banner.txt文件,文件中的内容放置这个图形的ASCII文本内容即可。

那么这样子的ASCII内容如何制作呢,其实有很多第三方的网站提供了工具,例如
https://www.bootschool.net/ascii,你可以到网站上轻松的制作并下载,可以选择各种类型的字体。

除了已经制作好的ASCII文本内容,Springboot还支持gif、jpg、png格式的图像,同样命名为banner.gif/jpg/png放置在resources文件夹下即可。

第二种实现自定义banner的选择是设置spring.banner.location属性指定要打印的文本文件的位置,或者使用
spring.banner.image.location指定图形文件的位置,如果文件所使用的不是UTF-8的编码,你还可以通过spring.banner.charset设置指定的文件编码。

注意:banner.gif/jpg/png的优先级高于banner.txt。

我们尝试将百度的Logo以banner.png的形式放置在resources目录下,重新启动应用,可以看到打印出了百度Logo的ASCII图形。

二、Banner打印的原理

根据以上过程的操作可以看到Springboot应用启动的过程中会根据设置的Banner图片或者ASCII图形进行解析,根据解析出来的图片像素点对应不同的字符,将ASCII字符打印出来。

我们追踪SpringApplicaiton.run()方法,可以看到以下的代码:

public ConfigurableApplicationContext run(String... args) {
  ......
  Banner printedBanner = printBanner(environment);
  ......
}
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.print()方法实现,我们一起来看看这个方法(以System.out分支为例):

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

可以看到,实际上Springboot提供了集中不同的Banner实现,有ImageBanner、TextBanner和自定义的fallbackBanner,会根据实际的情况选择不同的Banner实现进行Banner的打印。

以ImageBanner为例,跟踪发现其最终打印的实现代码如下:

private void printBanner(Environment environment, PrintStream out) throws IOException {
    int width = getProperty(environment, "width", Integer.class, 76);
    int height = getProperty(environment, "height", Integer.class, 0);
    int margin = getProperty(environment, "margin", Integer.class, 2);
    boolean invert = getProperty(environment, "invert", Boolean.class, false);
    BitDepth bitDepth = getBitDepthProperty(environment);
    PixelMode pixelMode = getPixelModeProperty(environment);
    Frame[] frames = readFrames(width, height);
    for (int i = 0; i < frames.length; i++) {
      if (i > 0) {
        resetCursor(frames[i - 1].getImage(), out);
      }
      printBanner(frames[i].getImage(), margin, invert, bitDepth, pixelMode, out);
      sleep(frames[i].getDelayTime());
    }
  }
private void printBanner(BufferedImage image, int margin, boolean invert, BitDepth bitDepth, PixelMode pixelMode,
      PrintStream out) {
    AnsiElement background = invert ? AnsiBackground.BLACK : AnsiBackground.DEFAULT;
    out.print(AnsiOutput.encode(AnsiColor.DEFAULT));
    out.print(AnsiOutput.encode(background));
    out.println();
    out.println();
    AnsiElement lastColor = AnsiColor.DEFAULT;
    AnsiColors colors = new AnsiColors(bitDepth);
    for (int y = 0; y < image.getHeight(); y++) {
      for (int i = 0; i < margin; i++) {
        out.print(" ");
      }
      for (int x = 0; x < image.getWidth(); x++) {
        Color color = new Color(image.getRGB(x, y), false);
        AnsiElement ansiColor = colors.findClosest(color);
        if (ansiColor != lastColor) {
          out.print(AnsiOutput.encode(ansiColor));
          lastColor = ansiColor;
        }
        out.print(getAsciiPixel(color, invert, pixelMode));
      }
      out.println();
    }
    out.print(AnsiOutput.encode(AnsiColor.DEFAULT));
    out.print(AnsiOutput.encode(AnsiBackground.DEFAULT));
    out.println();
  }
public enum PixelMode {
    /**
     * Use text chars for pixels.
     */
    TEXT(' ', '.', '*', ':', 'o', '&', '8', '#', '@'),
    /**
     * Use unicode block chars for pixels.
     */
    BLOCK(' ', '\u2591', '\u2592', '\u2593', '\u2588');
    private char[] pixels;
    PixelMode(char... pixels) {
      this.pixels = pixels;
    }
    char[] getPixels() {
      return this.pixels;
    }
  }

可以看到对于图片像素的解析过程以及对于打印出来的字符的配置,类似的可以自己实现自定义的Banner打印类,根据自己的需要设置打印不同的字符,通过
SpringApplicaiton.setBanner(Banner banner)来使用自定义的Banner。

相关文章
|
Java 程序员
自定义Springboot启动Banner
自定义Springboot启动Banner
146 0
SpringBoot自定义banner,配置端口号和项目路径(二)下
SpringBoot自定义banner,配置端口号和项目路径(二)
219 0
SpringBoot自定义banner,配置端口号和项目路径(二)下
|
Java 应用服务中间件
SpringBoot自定义banner,配置端口号和项目路径(二)中
SpringBoot自定义banner,配置端口号和项目路径(二)
184 0
SpringBoot自定义banner,配置端口号和项目路径(二)中
|
Java Spring
SpringBoot自定义banner,配置端口号和项目路径(二)上
SpringBoot自定义banner,配置端口号和项目路径(二)
351 0
SpringBoot自定义banner,配置端口号和项目路径(二)上
|
Java 应用服务中间件 Spring
SpringBoot自定义banner,配置端口号和项目路径(二)
本文主要讲解点:1. 自定义banner2. 配置Tomcat服务器的端口号和路径3. 配置jetty服务器4. 配置文件的优化级
393 0
SpringBoot自定义banner,配置端口号和项目路径(二)
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
173 1
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
111 62
|
4天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
39 13
|
12天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
75 2