1)、准备环境
- 执行ApplicationContextInitializer.initialize()
- 监听器SpringApplicationRunListener回调contextPrepared
- 加载主配置类定义信息
- 监听器SpringApplicationRunListener回调contextLoaded
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//判断当前容器环境,判断是SERVLET还是webmvc还是REACTIVE
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//从类路径下查找META-INF/spring.factories配置的所有ApplicationContextInitializer,然后保存起来。
setInitializers((Collection)
getSpringFactoriesInstances(ApplicationContextInitializer.class));
//从类路径下查找META-INF/spring.factories配置的所有ApplicationListener,然后保存起来。
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中,找到带有main方法的主配置类
this.mainApplicationClass = deduceMainApplicationClass();
}
2)、刷新启动IOC容器
- 扫描加载所有容器中的组件
- 包括从META-INF/spring.factories中获取所有的EnableAutoConfiguration组件
3)、回调容器中所有ApplicationRunner、CommandLineRunner的run方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//获取SpringApplicationRunListeners ;从类路径下META-INF/spring.factories
SpringApplicationRunListeners listeners = getRunListeners(args);
//循环遍历获取的listener,然后执行starting方法,启动起来。
listeners.starting();
try {
//封装命令行参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//创建完成后回调SpringApplicationRunListeners.prepareEnvironment()方法,准备环境。
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
//打印Banner图标
Banner printedBanner = printBanner(environment);
//创建ApplicationContext容器,会根据类型来判断创建容器种类
context = createApplicationContext();
//异常分析报告
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//准备容器上下文环境;applyInitializers(context):内部逻辑会回调上方ApplicationContextInitializer对象的initialize方法。还要回调所有的SpringApplicationRunListener对象的contextPrepared方法。运行完之后回调SpringApplicationRunListener的contextLoaded方法
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新容器,初始化容器的所有组件,包括内嵌的web容器
refreshContext(context);
//从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调,并且有次序。ApplicationRunner先回调,CommandLineRunner后回调。
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//调用SpringApplicationRunListeners的所有running方法,进行事件发布。
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
//整个spring容器启动完毕,返回带有所有资源的ioc容器
return context;
}
4)、监听器SpringApplicationRunListener回调running
网友评论