banner
我们是不是经常看到别人的项目启动的时候又高大上的banner,那这个banner怎么配置的呢?
如何配置就不讲了,随便贴了个:springboot 定制个性 banner
我们来看看springboot是怎么玩的。
/**
* Interface class for writing a banner programmatically.
*
* @author Phillip Webb
* @author Michael Stummvoll
* @author Jeremy Rickard
* @since 1.2.0
*/
@FunctionalInterface
public interface Banner {
/**
* Print the banner to the specified print stream.
* @param environment the spring environment
* @param sourceClass the source class for the application
* @param out the output print stream
*/
void printBanner(Environment environment, Class<?> sourceClass, PrintStream out);
/**
* An enumeration of possible values for configuring the Banner.
*/
enum Mode {
/**
* Disable printing of the banner.
*/
OFF,
/**
* Print the banner to System.out.
*/
CONSOLE,
/**
* Print the banner to the log file.
*/
LOG
}
}
Banner是一个接口,只有一个printBanner方法,然后有个Banner.Mode枚举,类型有三种:OFF、CONSOLE、LOG。应该不用多解释了。
再看看有几种实现:
接着看print方法:
private Banner printBanner(ConfigurableEnvironment environment) {
//如果SpringApplication配置的BannerMode是OFF呢,那就不打印
//private Banner.Mode bannerMode = Banner.Mode.CONSOLE;
//springApplication中设置的默认mode是控制台
if (this.bannerMode == Banner.Mode.OFF) {
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);
}
这里看到new SpringApplicationBannerPrinter(resourceLoader, this.banner);
前面应该没设置过banner属性,那这里应该是null才对,为了确保万一,debug查看下:
最后return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
就先以CONSOLE为例看看吧,LOG应该只是输出位置不同而已。
getBanner
private Banner getBanner(Environment environment) {
Banners banners = new Banners();
//获取image banner
banners.addIfNotNull(getImageBanner(environment));
//获取text banner
banners.addIfNotNull(getTextBanner(environment));
if (banners.hasAtLeastOneBanner()) {
return banners;
}
if (this.fallbackBanner != null) {
return this.fallbackBanner;
}
return DEFAULT_BANNER;
}
getImageBanner
先看看图片Banner
private Banner getImageBanner(Environment environment) {
//从配置里面获取location,BANNER_IMAGE_LOCATION_PROPERTY=“spring.banner.image.location”
String location = environment.getProperty(BANNER_IMAGE_LOCATION_PROPERTY);
//如果有配置location,则从location获取源,并且返回一个ImageBanner
if (StringUtils.hasLength(location)) {
Resource resource = this.resourceLoader.getResource(location);
return resource.exists() ? new ImageBanner(resource) : null;
}
//如果没配spring.banner.image.location,居然自己去遍历源目录,匹配后缀为IMAGE_EXTENSION的图片
//static final String[] IMAGE_EXTENSION = { "gif", "jpg", "png" };
for (String ext : IMAGE_EXTENSION) {
Resource resource = this.resourceLoader.getResource("banner." + ext);
if (resource.exists()) {
return new ImageBanner(resource);
}
}
return null;
}
banner这么强大?居然可以直接获取图片,以前百度上只教了txt的,搞个鸟试下
哈哈,虽然有点丑,不过样子还是可以
这里顺便掏出小本本记下笔记,banner设置的优先级:
- 通过spring.banner.image.location指定
- 通过在socures文件下面添加图片指定,优先级是【“gif”, “jpg”, “png”】
getTextBanner
private Banner getTextBanner(Environment environment) {
//static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
//static final String DEFAULT_BANNER_LOCATION = "banner.txt";
//从指定的目录下找banner.txt,如果找到了,就构建Banner
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.txt来构建Banner了,这里我们没准备banner.txt,应该是返回null了。
回去看看getBanner:
private Banner getBanner(Environment environment) {
Banners banners = new Banners();
banners.addIfNotNull(getImageBanner(environment));
banners.addIfNotNull(getTextBanner(environment));
//如果至少有一个Banner就直接返回banners
if (banners.hasAtLeastOneBanner()) {
return banners;
}
//如果banner回调不是null,返回回调
//我记得没配置过这个,应该是null
if (this.fallbackBanner != null) {
return this.fallbackBanner;
}
//返回默认Banner
return DEFAULT_BANNER;
}
DEFAULT_BANNER
fallbackBanner先不管了,来看看DEFAULT_BANNER,应该及时我们平时看到的那个了:
private static final Banner DEFAULT_BANNER = new SpringBootBanner();
/**
* Default Banner implementation which writes the 'Spring' banner.
*
* @author Phillip Webb
*/
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();
}
}
好像没什么好说的。