SpringBoot 启动流程
SpringBoot 启动流程
目录
1. 启动类 main 方法
启动类中的 main 方法做为入口,直接使用 SpringApplication 类的静态方法调用 run()方法,传入当前main方法所在的类。
public static void main(String[] args) {
SpringApplication.run(Sb2Application.class, args);
}
2. SpringApplication调用 run 方法
run方法里面将 传入的类包装成class 数组再次调用了另一个 静态的 run方法
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
另一个静态方法 new 一个 SpringApplication 的实例对象并且调用对象的 run方法,传入 main 方法所在的类,并出入args
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
上面步骤最后调用方法做了两件事,
第一件是调用 SpringApplication的构造器
第二件是低啊用了对象级别的 run 方法
3. SpringApplication 默认构造方法调用
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
//① 初始化 resourceLoader 这个默认为空
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
//② 初始化 primarySource 属性,是传入近来类的class 转换成的 Set 数据集,赋给了primarySource
this.primarySources = new LinkedHashSet<> (Arrays.asList(primarySources));
//③ 初始化 webApplicationType 字段,表明该容器跑的是哪类web 容器默认是servletw
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//④ 初始化上下文初始类的工厂类,读取默认的配置文件创建出上下文的实例放入实例工厂对象中
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
//⑤ 初始化监听器类的工厂类,读取默认配置文件创建出所有监听器放入对应的工厂类中
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// ⑥ 推断出当前启动容器的对象也就是入口类对应的对象
this.mainApplicationClass = deduceMainApplicationClass();
}
4. 调用 run 方法
public ConfigurableApplicationContext run(String... args) {
// 1. 开启计时
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 2.声明 ConfigurableApplicationContext 对象
ConfigurableApplicationContext context = null;
// 3.创建 一个Collection<SpringBootExceptionReporter> 对象
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 4.设置是该应用程序,即使没有检测到显示器,也允许其启动
configureHeadlessProperty();
// 5.获取创建的SpringApplicationRunListeners 监听器,并触发启动事件
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
// 6.新建 ApplicationArguments对象
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 7.新建 ConfigurableEnvironment 对象
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 8.设置需要忽略的 bean
configureIgnoreBeanInfo(environment);
// 9.打印 Banner
Banner printedBanner = printBanner(environment);
// 10.创建ApplicationContext对象
context = createApplicationContext();
// 11.创建exceptionReporters对象
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context);
// 13.准备 context
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 14.刷新 context (重要)
refreshContext(context);
// 15.刷新后的方法调用
afterRefresh(context, applicationArguments);
// 16.停止计时
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 {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure
(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
坚持做好每件事,然后再做下一件。