来源:https://segmentfault.com/a/1190000019038272?utm_source=tag-newest
SpringBoot的一大优势就是Starter,由于SpringBoot有很多开箱即用的Starter依赖,使得我们开发变得简单,我们不需要过多的关注框架的配置。
在日常开发中,我们也会自定义一些Starter,特别是现在微服务框架,我们一个项目分成了多个单体项目,而这些单体项目中会引用公司的一些组件,这个时候我们定义Starter,可以使这些单体项目快速搭起,我们只需要关注业务开发。
在此之前我们再深入的了解下SpringBoot启动原理。而后再将如何自定义starter。
二、 启动原理
要想了解启动原理,我们可以Debug模式跟着代码一步步探究,我们从入口方法开始:
public static ConfigurableApplicationContext run(Class>[] primarySources,String[] args) {
return new SpringApplication(primarySources).run(args);
}
这里是创建一个SpringApplication对象,并调用了run方法
2.1 创建SpringApplication对象
public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
//保存主配置类
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//确定web应用类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中找到有main方法的主配置类
this.mainApplicationClass = deduceMainApplicationClass();
}
从这个方法中可以看出,这个
第一步:保存主配置类。
第二步:确定web应用类型。
第三步:setInitializers方法,这个方法走我们看带入的参数是getSpringFactoriesInstances(ApplicationContextInitializer.class),我们再往下查看getSpringFactoriesInstances
再进入这个方法:
这里就是从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer,然后再保存起来,放开断点,我们可以看到这个时候获取到的
第四步:从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener,原理也基本类似,进入断点