SpringBoot启动流程分析之设置系统属性spring.beaninfo.ignore、自定义banner图(五)
参考
 目录
 
文章目录
- SpringBoot启动流程分析之设置系统属性spring.beaninfo.ignore、自定义banner图(五)
- 1、设置sping.beaninfo.ignore属性
- 2、Banner图
- 2.1、输出banner图
 
- 3、自定义banner图
 
 
 
 
org.springframework.boot.SpringApplication#run(java.lang.String…)
public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			// 开始分析 
           //得到系统属性spring.beaninfo.ignore,如果为空设置为true
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			//其余部分忽略...
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}
		return context;
	}
流程分析
1、设置sping.beaninfo.ignore属性
private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) {            
        //得到系统属性spring.beaninfo.ignore,如果为空设置为true
	if (System.getProperty(
			CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) {
		Boolean ignore = environment.getProperty("spring.beaninfo.ignore",
				Boolean.class, Boolean.TRUE);
		System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME,
				ignore.toString());
	}
}
2、Banner图
private Banner printBanner(ConfigurableEnvironment environment) {
        //判断banner图输出模式,off为不输出,直接返回空
	if (this.bannerMode == Banner.Mode.OFF) {
		return null;
	}
        //得到resourceLoader
	ResourceLoader resourceLoader = (this.resourceLoader != null)
			? this.resourceLoader : new DefaultResourceLoader(getClassLoader());
        //实例化一个SpringApplicationBannerPrinter
	SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(
			resourceLoader, this.banner);
        //判断banner是否输出到日志文件
	if (this.bannerMode == Mode.LOG) {
		return bannerPrinter.print(environment, this.mainApplicationClass, logger);
	}
        //最后就是输出到控制台了,参数包括environment,主类,一个打印流System.out
	return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
}
Banner图的打印模式枚举值:
Mode.OFF :不输出
 Mode.CONSOLE:将输出到System.out,即控制台
 Mode.log:输出到日志文件
 可以通过SpringApplication对象设置打印模式。设置为OFF,即不输出Banner,启动后效果如下。
@SpringBootApplication
public class Application {
	public static void main(String[] args) {
//		SpringApplication.run(Application.class, args);
		
		SpringApplication application = new SpringApplication(Application.class);
		application.setBannerMode(Mode.OFF);
		ConfigurableApplicationContext context = application.run(args);
 
		context.close();
	}
}

2.1、输出banner图
new一个Banners对象,该对象内部有一个Banner对象的集合,下一步就是得到文本或者图片banner,然后添加到list中,不为空则返回该对象。在Banners的printBanner方法中循环调用对应ResourceBanner和ImageBanner的printBanner方法。
public Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
	Banner banner = getBanner(environment);
        //输出banner图
	banner.printBanner(environment, sourceClass, out);
	return new PrintedBanner(banner, sourceClass);
}
 
private Banner getBanner(Environment environment) {
	Banners banners = new Banners();
        //得到图片banner,如果不为空就添加到List集合中
	banners.addIfNotNull(getImageBanner(environment));
        //得到txt文本banner,同样不为空就添加到List集合中
	banners.addIfNotNull(getTextBanner(environment));
        //r如果List不为空,直接返回
	if (banners.hasAtLeastOneBanner()) {
		return banners;
	}
        //如果该banner对象不为空,返回该banner对象
	if (this.fallbackBanner != null) {
		return this.fallbackBanner;
	}
        //最后就是返回默认banner图,也就是我们看到的spring
	return DEFAULT_BANNER;
}
可以看到banner的配置项,默认位置,默认的txt文件名和支持的banner图片类型,图片名字也是banner加上后缀。如果存在txt文档,返回的就是ResourceBanner,存在图片banner返回的就是ImageBanner,如果不存在都是返回空,则使用默认的SpringBootBanner。也就是启动后看见的那个大大的Spring。
 
private Banner getBanner(Environment environment) {
		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;
	}
	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;
	}
	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;
	}
最后就是输出banner图了,System.out.println();
 
3、自定义banner图
在resources目录下新建一个banner.txt文件或者你也可以直接放一张图片到resources目录下,名字是banner.jpg(gif|png)。我的banner.txt内容如下。
可以到这个网站去生成banner图:生成banner图
















