springboot banner是怎麼加載的

前言

我們肯定很好奇,當我們啓動 springboot 的時候,這個下面的 banner 是怎麼打印出來的呢?


以及我們可不可以定製我們自己的banner,那我們就進入一下 SpringBoot 的源碼,看下他是怎麼加載的吧

PS:文章同步更新於Github–Java-Notes,如果某些圖片看不了可以直接從這個上面觀看

源碼分析

項目結構

入口

private Banner printBanner(ConfigurableEnvironment environment) {
  // 判斷是否關閉了 banner 打印模式 
  if (this.bannerMode == Banner.Mode.OFF) {
      return null;
   }
   // 初始化資源加載器
   ResourceLoader resourceLoader = (this.resourceLoader != null)
         ? this.resourceLoader : new DefaultResourceLoader(getClassLoader());
  // 初始化 banner 打印對象 
  SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(
         resourceLoader, this.banner);
  // 如果在 log中打印 banner
   if (this.bannerMode == Mode.LOG) {
      return bannerPrinter.print(environment, this.mainApplicationClass, logger);
   }
  // 如果在 控制檯打印banner
   return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}
// 只有三種模式,關閉 控制檯 和log文件中
enum Mode {

   /**
    * Disable printing of the banner.
    */
   OFF,

   /**
    * Print the banner to System.out.
    */
   CONSOLE,

   /**
    * Print the banner to the log file.
    */
   LOG

}
public Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
  // 獲取banner,看了這個我們就知道怎麼去更改 banner了 
  Banner banner = getBanner(environment);
  // 打印 banner
   banner.printBanner(environment, sourceClass, out);
   return new PrintedBanner(banner, sourceClass);
}
private Banner getBanner(Environment environment) {
  // 創建一個局部對象 Banners ,這個對象繼承自 Banner接口,內容很簡單,保存banner信息,添加banner方法,打印banner方法
   Banners banners = new Banners();
  // 添加banner ,這個裏面還有些道道
   banners.addIfNotNull(getImageBanner(environment));
   banners.addIfNotNull(getTextBanner(environment));
   if (banners.hasAtLeastOneBanner()) {
      return banners;
   }
   if (this.fallbackBanner != null) {
      return this.fallbackBanner;
   }
  // 如果都沒有,那麼就會打印默認的 banner, 我們都見過
   return DEFAULT_BANNER;
}
// 獲取 圖像banner 信息
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;
		}
  	// 如果配置文件中沒有指明,我們就讀取默認的配置,banner前綴開頭的,挨個遍歷匹配。按照 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
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();
   }

}

實驗

我們準備了 四個文件,gif、jpg、png、txt。打印出來是這樣的,上面是 gif的內容,下面是 txt的內容

我們在配置文件中指定文件,就不會按照默認的來進行顯示了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章