入口
SpringApplication的
Banner printedBanner = printBanner(environment);
斷點跟蹤
1.判斷當前的Banner打印位置
private Banner printBanner(ConfigurableEnvironment environment) {
//判斷banner是否關閉
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);
}
// 默認console 打印在控制檯
return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}
Mode是個枚舉類包括三個值:
2.默認打印SpringBoot內置的Banner
直接看print方法,因爲是走的控制檯,所以直接上面的最後一個return返回。
public Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
Banner banner = getBanner(environment);
banner.printBanner(environment, sourceClass, out);
return new PrintedBanner(banner, sourceClass);
}
private Banner getBanner(Environment environment) {
Banners banners = new Banners();
//獲取圖片Banner
banners.addIfNotNull(getImageBanner(environment));
//獲取文本Banner
banners.addIfNotNull(getTextBanner(environment));
if (banners.hasAtLeastOneBanner()) {
return banners;
}
if (this.fallbackBanner != null) {
return this.fallbackBanner;
}
return DEFAULT_BANNER;
}
如果不做配置,默認情況下這個方法會return一個null返回。
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);
}
// 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;
}
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的輸出會調用SpringBootBanner中的這個方法。
@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();
}
循環按照line去讀取定義的banner字符串。然後用StringBuilder拼接字符,調用printStream.println()進行打印。默認打印值:
3.打印自定義Banner.txt文件內容
文件位置和文件內容(bug game over)
if (banners.hasAtLeastOneBanner()) {
return banners;
}
這次調用print的時候是調用SpringApplicationBannerPrinter中的
@Override
public void printBanner(Environment environment, Class<?> sourceClass,
PrintStream out) {
for (Banner banner : this.banners) {
banner.printBanner(environment, sourceClass, out);
}
}
這方法會調用ResourceBanner這個類中的printBanner,
控制檯打印:
4.打印自定義圖片的Banner
public void printBanner(Environment environment, Class<?> sourceClass,PrintStream out)
最後會調用到
private void printBanner(BufferedImage image, int margin, boolean invert,
PrintStream out) {
AnsiElement background = (invert ? AnsiBackground.BLACK : AnsiBackground.DEFAULT);
out.print(AnsiOutput.encode(AnsiColor.DEFAULT));
out.print(AnsiOutput.encode(background));
out.println();
out.println();
AnsiColor lastColor = AnsiColor.DEFAULT;
for (int y = 0; y < image.getHeight(); y++) {
for (int i = 0; i < margin; i++) {
out.print(" ");
}
for (int x = 0; x < image.getWidth(); x++) {
Color color = new Color(image.getRGB(x, y), false);
AnsiColor ansiColor = AnsiColors.getClosest(color);
if (ansiColor != lastColor) {
out.print(AnsiOutput.encode(ansiColor));
lastColor = ansiColor;
}
out.print(getAsciiPixel(color, invert));
}
out.println();
}
out.print(AnsiOutput.encode(AnsiColor.DEFAULT));
out.print(AnsiOutput.encode(AnsiBackground.DEFAULT));
out.println();
}
通過字符數組把解析圖片得到的值進行替換。最後打印的Banner。
圖片的原型
5.打印自定義文本和圖片