首先看SpringApplication类的run方法内容,
public ConfigurableApplicationContext run(String… args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.started();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, ex);
throw new IllegalStateException(ex);
}
}
注意这一句内容Banner printedBanner = printBanner(environment); 我们继续进入 printBanner(environment) 方法如下
private Banner printBanner(ConfigurableEnvironment environment) {
if (this.bannerMode == Banner.Mode.OFF) {
return null;
}
if (printBannerViaDeprecatedMethod(environment)) {
return null;
}
ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader
: new DefaultResourceLoader(getClassLoader());
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);
}
这里我们看到,为了加载banner内容初始化了资源加载器ResourceLoader resourceLoader = this.resourceLoader != null ? this.resourceLoader
: new DefaultResourceLoader(getClassLoader());
很明显这个资源加载器传入了SpringApplicationBannerPrinter类初始化,我们再this.bannerMode 的值,默认为
private Banner.Mode bannerMode = Banner.Mode.CONSOLE;
所以执行return bannerPrinter.print(environment, this.mainApplicationClass, System.out); 这行,我们现在进入SpringApplicationBannerPrinter的print方法
public Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
Banner banner = getBanner(environment, this.fallbackBanner);
banner.printBanner(environment, sourceClass, out);
return new PrintedBanner(banner, sourceClass);
}
继续进入getBanner 方法查看,
private Banner getBanner(Environment environment, Banner definedBanner) {
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对象,注意这里getImageBanner(environment) ,继续进入
private Banner getImageBanner(Environment environment) {
String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
if (StringUtils.hasLength(location)) {
Resource resource = this.resourceLoader.getResource(location);
return (resource.exists() ? new ImageBanner(resource) : null);
}
for (String ext : IMAGE_EXTENSION) {
Resource resource = this.resourceLoader.getResource(“banner.” + ext);
if (resource.exists()) {
return new ImageBanner(resource);
}
}
return null;
}
这里很简单根据environment获取banner.image.location 对应location 获取图片封装为ImageBanner 对象打印,这里我们在environment 没有注入banner.image.location地址,所以这里返回null
继续进入getTextBanner(environment) 方法中查看
private Banner getTextBanner(Environment environment) {
String location = environment.getProperty(BANNER_LOCATION_PROPERTY,
DEFAULT_BANNER_LOCATION);
Resource resource = this.resourceLoader.getResource(location);
if (resource.exists()) {
return new ResourceBanner(resource);
}
return null;
}
这里和上面一样banner.location 从environment 中获取,很明显还是没有,但是不一样的的有一个默认值DEFAULT_BANNER_LOCATION 对应的值为banner.txt
到这里我们明白了,为什么打印banner.txt
以上分析自定义打印banner有三种方法:
1、在启动的时候调用SpringApplication的
public void setDefaultProperties(Map<String, Object> defaultProperties) {
this.defaultProperties = defaultProperties;
}
注入 banner.image.location 的地址,就会打印相应图片。
2、和第一种一样只是注入banner.location的地址,再没有设置第一种时也会打印banner
3、最简单一种,直接根目录下新建banner.txt 并写入内容,在没有前两种设置的情况下会打印banner