相信有部分猿宝宝们看到Springboot启动后打印出的图形文字特别感兴趣
这种类图形化称为banner,也就是横幅,像我们引入一些其他厂商的框架比如mybatis也会打印出banner
其实基于Springboot实现起来特别简单:
在resource下建一个banner.txt文件即可
我就直接输入一个笔名吧
POWER-J
启动下项目看看效果
看到了没,Spring被我的POWER-J替代了,不过有的猿宝宝会说,你这啥呀,也不是图形化的啊
别急,有现成的在线工具:
图片转图形文字
文字转图形文字
文字转图形文字2
作者随便选了个样式,来启动看下效果
作者通过查看源码,并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;
}
那作者为什么要看源码呢?上面的用法其实基本满足大家使用了,直接新增一个banner.txt即可。
其实通过官方文档和源码,能让你更加了解Springboot加载banner的机制
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类来实现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现有的一些工具类进行扩展,请期待吧!