SpringBoot的执行原理
每一个springboot项目都有一个主程序启动类,该类中有一个main方法,SpringBoot就是通过该main方法去调用SpringApplication.run()方法来启动Springboot的。
一,SpringAppliction的实例初始化创建
① 扫描spring的一些默认属性。
② this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); 通过这行代码将Springboot的主程序启动类存储起来。
③ this.webApplicationType = WebApplicationType.deduceFromClasspath(); 通过这段代码来判断当前webApplicationType的应用类型(servlet (传统的MVC)还是Reactive(Spring 5之后出现的交互是WebFlux的web应用))
④ this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); 通过这段代码来设置一些初始化器
⑤ this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)) 通过这段代码来设置一些监听器,
⑥ this.mainApplicationClass = this.deduceMainApplicationClass(); 用于推断并设置项目的main()方法的主程序启动类
二, 项目的初始化启动
①SpringApplicationRunListeners listeners = this.getRunListeners(args); listeners.starting();
通过上面的代码来获取监听器,并启动这些监听器。
② ConfigurableEnvironment environment = this.prepareEnvironment(listeners,applicationArguments);
this.configureIgnoreBeanInfo(environment);
通过的上面的代码可以看出,第二步是通过这些监听器和应用参数来构建一个springboot的配置环境
③ context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[]{ConfigurableApplicationContext.class}, new Object[]{context});
第三步创建spring的容器。
④ this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
容器的前置处理
⑤ this.refreshContext(context);
刷新容器。
⑥ this.afterRefresh(context, applicationArguments); stopWatch.stop();
if(this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
容器的后置处理。
⑦ listeners.started(context);
this.callRunners(context, applicationArguments);
listeners.running(context);
return context;
发出结束的执行请求,返回容器。