
Springboot 2.2.3.RELEASE
SpringApplication.run()是Springboot启动入口
// 指定资源文件加载策略,可以指定加载配置文件路径,也可以是类路径;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
// 主要bean Class集合
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 应用类型,默认为servlet 通过是否包含指定类(能Classloader加载)确定。
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 初始化ApplicationContextInitializer 通过META-INF/spring.factories(Spring-bean、springboot-autoconfig)配置来决策初始化范围,并将实现ApplicationContextInitializer(接口)相关的Bean实例化。
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
初始化配置接口清单:初始化ApplicationContextInitializer的实例包括
// 同样的方式找出实现ApplicationListener接口的Bean进行实例化
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 实例化结果
// 找到入口类,原理:创建一个运行时异常,获得堆栈信息来一层层的判断,来获得包含main方法的Class
this.mainApplicationClass = deduceMainApplicationClass();// StopWatch监控 其实就是一个计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 配置Headless模式 java.awt.headless是J2SE的一种模式用于在缺少显示屏、键盘或者鼠标时的系统配置,很多监控工具如jconsole 需要将该值设置为true.
configureHeadlessProperty();
// 加载并启动SpringApplicationRunListeners监听器,实例化过程同上setListeners一致
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
// 最终实例化的SpringApplicationRunListeners实例为EventPublishingRunListener,EventPublishingRunListener实例化时将前面在构建SpringApplication实例过程中设置的监听器(listeners)逐个添加到initialMulticaster中(管理和发布事件)
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 准备应用环境 创建环境(根据webApplicationType创建)并加载各种配置属性,并广播environmentPrepared事件,并与SpringApplication进行绑定
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 这一步配置没看懂要干啥,知道的可以评论~
configureIgnoreBeanInfo(environment);
// Banner打印
Banner printedBanner = printBanner(environment);
// 创建Context,与webApplicationType对应[SERVLET:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext]
context = createApplicationContext();
// 获取异常分析器,获取方式与listener等一致
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// 准备环境,设置上下文,这一步会讲new中得到initializers进行上下文设置,并发布contextPrepared事件。接下来还会进行单例Bean的创建、延迟策略的设定,最后发布contextLoaded事件
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 刷新Context 各种Processors 、消息、事件及listener的初始化,包括配置文件的加载(如application.yml)并注册一个JVM关闭时的钩子
refreshContext(context);
// 空的
afterRefresh(context, applicationArguments);
//结束当前计时器
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
//执行ApplicationRunner、CommandLineRunner
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;