咱们在启动 Spring Boot 程序时,有 SpringBoot 的 Banner 信息,那么如何自定义成本人我的项目的信息呢?@pdai
-
SpringBoot 开发 – 如何定制本人的 Banner?还能用图片?
- 什么是 Banner
- 如何更改 Banner
-
文字 Banner 的设计
- 一些设计 Banner 的网站
- IDEA 中 Banner 的插件
- 其它工具
- Banner 中其它配置信息
- 动画 Banner 的设计
-
进一步思考
- 图片 Banner 是如何起作用的?
- 示例源码
- 更多内容
什么是 Banner
咱们在启动 Spring Boot 程序时,有如下 Banner 信息:
那么如何自定义成本人我的项目的名称呢?
如何更改 Banner
更改 Banner 有如下几种形式:
- banner.txt 配置 (最罕用)
在 application.yml 中增加配置
spring:
banner:
charset: UTF-8
location: classpath:banner.txt
在 resource 下创立 banner.txt,内容自定义:
----welcome----
https://pdai.tech
---------------
批改后,重启的 app 的成果
- SpringApplication 启动时设置参数
SpringApplication application = new SpringApplication(App.class);
/**
* Banner.Mode.OFF: 敞开;
* Banner.Mode.CONSOLE: 控制台输入,默认形式;
* Banner.Mode.LOG: 日志输入形式;
*/
application.setBannerMode(Banner.Mode.OFF); // here
application.run(args);
SpringApplication 还能够设置自定义的 Banner 的接口类
文字 Banner 的设计
如何设计下面的文字呢?
一些设计 Banner 的网站
能够通过这个网站进行设计:patorjk Banner
比方:
咱们批改 banner.txt, 运行的成果如下
IDEA 中 Banner 的插件
IDEA 中也有插件,不过没有预览性能
其它工具
http://www.network-science.de…
http://www.degraeve.com/img2t…
http://www.bootschool.net/ascii
Banner 中其它配置信息
除了文件信息,还有哪些信息能够配置呢?比方 Spring 默认还带有 SpringBoot 以后的版本号信息。
在 banner.txt 中,还能够进行一些设置:
# springboot 的版本号
${spring-boot.version}
# springboot 的版本号后面加 v 后上括号
${spring-boot.formatted-version}
# MANIFEST.MF 文件中的版本号
${application.version}
# MANIFEST.MF 文件的版本号后面加 v 后上括号
${application.formatted-version}
# MANIFEST.MF 文件中的程序名称
${application.title}
# ANSI 样色 / 款式等
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME})
简略的测试如下( 留神必须打包出 Jar, 才会生成 resources/META-INF/MANIFEST.MF):
动画 Banner 的设计
那我能不能设置动静的 Banner 呢?比方一个图片?
SpringBoot2 是反对图片模式的 Banner,
spring:
main:
banner-mode: console
show-banner: true
banner:
charset: UTF-8
image:
margin: 0
height: 10
invert: false
location: classpath:pdai.png
成果如下(须要抉择适合的照片,不然成果不好, 所以这种形式很少应用),
留神:格局不能太大,不然会报错
org.springframework.boot.ImageBanner : Image banner not printable: class path resource [banner.gif] (class java.lang.ArrayIndexOutOfBoundsException: '4096')
进一步思考
图片 Banner 是如何起作用的?
发现 Springboot 能够把图片转换成 ASCII 图案,那么它是怎么做的呢?以此为例,咱们看下 Spring 的 Banner 是如何生成的呢?
-
获取 Banner
- 优先级是环境变量中的 Image 优先, 格局在 IMAGE_EXTENSION 中
- 而后才是 banner.txt
- 没有的话就用 SpringBootBanner
-
如果是图片
- 获取图片 Banner(属性配置等)
- 转换成 ascii
获取 banner
class SpringApplicationBannerPrinter {
static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
static final String BANNER_IMAGE_LOCATION_PROPERTY = "spring.banner.image.location";
static final String DEFAULT_BANNER_LOCATION = "banner.txt";
static final String[] IMAGE_EXTENSION = new String[]{"gif", "jpg", "png"};
private static final Banner DEFAULT_BANNER = new SpringBootBanner(); // 默认的 Spring Banner
private final ResourceLoader resourceLoader;
private final Banner fallbackBanner;
// 获取 Banner,优先级是环境变量中的 Image 优先, 格局在 IMAGE_EXTENSION 中,而后才是 banner.txt
private Banner getBanner(Environment environment) {SpringApplicationBannerPrinter.Banners banners = new SpringApplicationBannerPrinter.Banners();
banners.addIfNotNull(this.getImageBanner(environment));
banners.addIfNotNull(this.getTextBanner(environment));
if (banners.hasAtLeastOneBanner()) {return banners;} else {return this.fallbackBanner != null ? this.fallbackBanner : DEFAULT_BANNER;}
}
获取图片 Banner
private Banner getImageBanner(Environment environment) {String location = environment.getProperty("spring.banner.image.location");
if (StringUtils.hasLength(location)) {Resource resource = this.resourceLoader.getResource(location);
return resource.exists() ? new ImageBanner(resource) : null;
} else {String[] var3 = IMAGE_EXTENSION;
int var4 = var3.length;
for(int var5 = 0; var5 < var4; ++var5) {String ext = var3[var5];
Resource resource = this.resourceLoader.getResource("banner." + ext);
if (resource.exists()) {return new ImageBanner(resource);
}
}
return null;
}
}
获取图片的配置等
private void printBanner(Environment environment, PrintStream out) throws IOException {int width = (Integer)this.getProperty(environment, "width", Integer.class, 76);
int height = (Integer)this.getProperty(environment, "height", Integer.class, 0);
int margin = (Integer)this.getProperty(environment, "margin", Integer.class, 2);
boolean invert = (Boolean)this.getProperty(environment, "invert", Boolean.class, false); // 图片的属性
BitDepth bitDepth = this.getBitDepthProperty(environment);
ImageBanner.PixelMode pixelMode = this.getPixelModeProperty(environment);
ImageBanner.Frame[] frames = this.readFrames(width, height); // 读取图片的帧
for(int i = 0; i < frames.length; ++i) {if (i > 0) {this.resetCursor(frames[i - 1].getImage(), out);
}
this.printBanner(frames[i].getImage(), margin, invert, bitDepth, pixelMode, out);
this.sleep(frames[i].getDelayTime());
}
}
转换成 ascii
private void printBanner(BufferedImage image, int margin, boolean invert, BitDepth bitDepth, ImageBanner.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) {
int x;
for(x = 0; x < margin; ++x) {out.print(" ");
}
for(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(this.getAsciiPixel(color, invert, pixelMode)); // // 像素点转换成字符输入
}
out.println();}
out.print(AnsiOutput.encode(AnsiColor.DEFAULT));
out.print(AnsiOutput.encode(AnsiBackground.DEFAULT));
out.println();}
示例源码
https://github.com/realpdai/t…
更多内容
辞别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈常识体系 (https://pdai.tech)