SpringBoot版本:2.1.1 ==》启动流程分析汇总
接上篇博客Spring Boot 2.1.1(十)启动流程分析之ApplicationEnvironmentPreparedEvent事件发布。
目录
流程分析
1、设置spring.beaninfo.ignore属性
2、Banner图
public ConfigurableApplicationContext run(String... args) {
....
try {
//本篇内容从本行开始记录
//得到系统属性spring.beaninfo.ignore,如果为空设置为true
configureIgnoreBeanInfo(environment);
//打印banner图
Banner printedBanner = printBanner(environment);
//本篇内容记录到这,后续更新
....
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
}
至于该属性的作用是什么,暂时还不知道。
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());
}
}
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图的打印模式枚举值:
可以通过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();
}
}
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 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();是不是看到熟悉的东西了。
在resources目录下新建一个banner.txt文件或者你也可以直接放一张图片到resources目录下,名字是banner.jpg(gif|png)。我的banner.txt内容如下。
启动效果如下。
在放张图片,名字是banner.jpg。
图片就是大艾斯,可以看到,两个都输出了。不过图片输出的有点抽象,哈哈哈。
可以到这个网站去生成banner图:生成banner图