SpringBoot
启动之后,默认会打印SpringBoot
的Banner
,想要修改它,网上有很多的文章介绍,只要在resources
中添加定义的banner.txt
或者banner.png
等都可以,但是他是怎么样的一个加载过程呢,我们来看下SpringBoot
启动之后,对于Banner
的处理,常见入口函数如下
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
在调用SpringApplication
的run
方法之后
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
这里有个专门用于输出banner
的方法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);
}
在此处可以看到,如果我们没有定义resourceLoader
,那么就会采用默认的DefaultResourceLoader
来加载资源。同时,会创建一个SpringApplicationBannerPrinter
来进行banner
输出,默认的banner
是什么?
static final String DEFAULT_BANNER_LOCATION = "banner.txt";
static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };
private static final Banner DEFAULT_BANNER = new SpringBootBanner();
如果我们在resources
中指定了banner.txt
或者图片类型的banner,那么就会从resources
中加载,否则就会采用默认的SpringBootBanner
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;
}
那么默认的SpringBootBanner
就是我们常见的输出形式,我们看一下它的源码
class SpringBootBanner implements Banner {
private static final String[] BANNER = { "", " . ____ _ __ _ _",
" /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\", "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
" \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )", " ' |____| .__|_| |_|_| |_\\__, | / / / /",
" =========|_|==============|___/=/_/_/_/" };
private static final String SPRING_BOOT = " :: Spring Boot :: ";
private static final int STRAP_LINE_SIZE = 42;
@Override
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream printStream) {
for (String line : BANNER) {
printStream.println(line);
}
String version = SpringBootVersion.getVersion();
version = (version != null) ? " (v" + version + ")" : "";
StringBuilder padding = new StringBuilder();
while (padding.length() < STRAP_LINE_SIZE - (version.length() + SPRING_BOOT.length())) {
padding.append(" ");
}
printStream.println(AnsiOutput.toString(AnsiColor.GREEN, SPRING_BOOT, AnsiColor.DEFAULT, padding.toString(),
AnsiStyle.FAINT, version));
printStream.println();
}
}
是不是很熟悉,当然,知道了原理,那么要修改它就很简单了,我们可以直接指定banner.txt
,也可以指定ResourceBanner
从我们希望的地方加载banner
,比如直接从网络图片来加载
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(DemoApplication.class);
try {
ImageBanner imageBanner = new ImageBanner(new UrlResource("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201511%2F03%2F20151103192514_JMKza.thumb.400_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638846183&t=c62cdc650738467a80c637a5dc8a33e1"));
springApplication.setBanner(imageBanner);
} catch (MalformedURLException e) {
e.printStackTrace();
}
springApplication.run(args);
}
启动效果如图
image.png
当然,也可以直接使用指定的字符串
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(DemoApplication.class);
try {
String felix = " \n" +
" \n" +
"FFFFFFFFFFFFFFFFFFFFFF EEEEEEEEEEEEEEEEEEEEEE LLLLLLLLLLL IIIIIIIIII XXXXXXX XXXXXXX\n" +
"F::::::::::::::::::::F E::::::::::::::::::::E L:::::::::L I::::::::I X:::::X X:::::X\n" +
"F::::::::::::::::::::F E::::::::::::::::::::E L:::::::::L I::::::::I X:::::X X:::::X\n" +
"FF::::::FFFFFFFFF::::F EE::::::EEEEEEEEE::::E LL:::::::LL II::::::II X::::::X X::::::X\n" +
" F:::::F FFFFFF E:::::E EEEEEE L:::::L I::::I XXX:::::X X:::::XXX\n" +
" F:::::F E:::::E L:::::L I::::I X:::::X X:::::X \n" +
" F::::::FFFFFFFFFF E::::::EEEEEEEEEE L:::::L I::::I X:::::X:::::X \n" +
" F:::::::::::::::F E:::::::::::::::E L:::::L I::::I X:::::::::X \n" +
" F:::::::::::::::F E:::::::::::::::E L:::::L I::::I X:::::::::X \n" +
" F::::::FFFFFFFFFF E::::::EEEEEEEEEE L:::::L I::::I X:::::X:::::X \n" +
" F:::::F E:::::E L:::::L I::::I X:::::X X:::::X \n" +
" F:::::F E:::::E EEEEEE L:::::L LLLLLL I::::I XXX:::::X X:::::XXX\n" +
"FF:::::::FF EE::::::EEEEEEEE:::::E LL:::::::LLLLLLLLL:::::L II::::::II X::::::X X::::::X\n" +
"F::::::::FF E::::::::::::::::::::E L::::::::::::::::::::::L I::::::::I X:::::X X:::::X\n" +
"F::::::::FF E::::::::::::::::::::E L::::::::::::::::::::::L I::::::::I X:::::X X:::::X\n" +
"FFFFFFFFFFF EEEEEEEEEEEEEEEEEEEEEE LLLLLLLLLLLLLLLLLLLLLLLL IIIIIIIIII XXXXXXX XXXXXXX\n" +
" \n" +
" \n" +
" \n" +
" \n" +
" \n" +
" \n" +
" ";
ResourceBanner resourceBanner = new ResourceBanner(new ByteArrayResource(felix.getBytes()));
springApplication.setBanner(resourceBanner);
} catch (MalformedURLException e) {
e.printStackTrace();
}
springApplication.run(args);
}
执行效果如图
最后就是网上常见的方案了,直接放置一个
banner.txt
,然后SpringBoot
启动之后就会自动加载了,这中方案网上很多,就不再介绍了。
网友评论