一.spring boot 版本 2.1.7.RELEASE
二.源码逻辑思维导图
三.源码分析
看注释
/**
* 根据Banner.Mode.OFF判断是否打印,打印到日志文件还是打印到控制台
* @param environment
* @return
*/
private Banner printBanner(ConfigurableEnvironment environment) {
//不打印
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 == Banner.Mode.LOG) {
return bannerPrinter.print(environment, this.mainApplicationClass, logger);
}
//控制台输出
return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}
/**
* 控制台输出
* @param environment
* @param sourceClass
* @param out
* @return
*/
public Banner print(Environment environment, Class> sourceClass, PrintStream out) {
//1.获取banner 图片 文字文件 文字图案三种
Banner banner = getBanner(environment);
//2.打印banner
banner.printBanner(environment, sourceClass, out);
return new SpringApplicationBannerPrinter.PrintedBanner(banner, sourceClass);
}
/**
* 获取banner
* @param environment
* @return
*/
private Banner getBanner(Environment environment) {
SpringApplicationBannerPrinter.Banners banners = new SpringApplicationBannerPrinter.Banners();
//添加图片banner
banners.addIfNotNull(getImageBanner(environment));
//添加文字文件banner
banners.addIfNotNull(getTextBanner(environment));
if (banners.hasAtLeastOneBanner()) {
return banners;
}
if (this.fallbackBanner != null) {
return this.fallbackBanner;
}
//返回默认banner
return DEFAULT_BANNER;
}
/**
* 获取图片banner
* @param environment
* @return
*/
private Banner getImageBanner(Environment environment) {
//是否有配置图片banner,有的话直接返回
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;
}
//resources里面是否有banner.gif banner.jpg banner.png的图片,有的话直接返回
for (String ext : IMAGE_EXTENSION) {
Resource resource = this.resourceLoader.getResource("banner." + ext);
if (resource.exists()) {
return new ImageBanner(resource);
}
}
//没有的话返回null
return null;
}
/**
* 获取文本文件banner
* @param environment
* @return
*/
private Banner getTextBanner(Environment environment) {
//是否有配置文本文件banner,如果没有默认取banner.txt
String location = environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION);
//判断文件是否存在,存在返回文件,不存在返回null
Resource resource = this.resourceLoader.getResource(location);
if (resource.exists()) {
return new ResourceBanner(resource);
}
return null;
}
默认的字符串banner打印
/**
* 默认图案
*/
private static final String[] BANNER = { "", " . ____ _ __ _ _",
" /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\", "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
" \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )", " ' |____| .__|_| |_|_| |_\\__, | / / / /",
" =========|_|==============|___/=/_/_/_/" };
/**
* 默认标题
*/
private static final String SPRING_BOOT = " :: Spring Boot :: ";
/**
* 默认空格数
*/
private static final int STRAP_LINE_SIZE = 42;
/**
* 默认的字符串banner打印
* @param environment
* @param sourceClass
* @param printStream
*/
@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
/**
* 文本文件banner打印
* @param environment
* @param sourceClass
* @param out
*/
@Override
public void printBanner(Environment environment, Class> sourceClass, PrintStream out) {
try {
//从文件流获取打印内容,编码,默认编码utf-8
String banner = StreamUtils.copyToString(this.resource.getInputStream(),
environment.getProperty("spring.banner.charset", Charset.class, StandardCharsets.UTF_8));
//${}属性替换
for (PropertyResolver resolver : getPropertyResolvers(environment, sourceClass)) {
banner = resolver.resolvePlaceholders(banner);
}
//打印
out.println(banner);
}
catch (Exception ex) {
logger.warn(
"Banner not printable: " + this.resource + " (" + ex.getClass() + ": '" + ex.getMessage() + "')",
ex);
}
}
图片banner打印
/**
* 图片banner打印
* @param environment
* @param sourceClass
* @param out
*/
public void printBanner(Environment environment, Class> sourceClass, PrintStream out) {
String headless = System.getProperty("java.awt.headless");
try {
//设置headless模式为true
System.setProperty("java.awt.headless", "true");
//调用Java画图api进行打印
printBanner(environment, out);
}
catch (Throwable ex) {
logger.warn("Image banner not printable: " + this.image + " (" + ex.getClass() + ": '" + ex.getMessage()
+ "')");
logger.debug("Image banner printing failure", ex);
}
finally {
if (headless == null) {
System.clearProperty("java.awt.headless");
}
else {
System.setProperty("java.awt.headless", headless);
}
}
}
/**
* 调用JavaAPI进行打印操作
* @param environment
* @param out
* @throws IOException
*/
private void printBanner(Environment environment, PrintStream out) throws IOException {
int width = getProperty(environment, "width", Integer.class, 76);
int height = getProperty(environment, "height", Integer.class, 0);
int margin = getProperty(environment, "margin", Integer.class, 2);
boolean invert = getProperty(environment, "invert", Boolean.class, false);
ImageBanner.Frame[] frames = readFrames(width, height);
for (int i = 0; i < frames.length; i++) {
if (i > 0) {
resetCursor(frames[i - 1].getImage(), out);
}
printBanner(frames[i].getImage(), margin, invert, out);
sleep(frames[i].getDelayTime());
}
}