项目搭建完成后我们就可以通过打断点的方式追踪到springboot启动过程中被调用到的每一个方法。
1.创建SpringApplication实例
在run方法上打个断点,启动项目,开始根据项目的启动
一直step into进去,发现在run方法里面new了一个上下文对象SpringApplication。
SpringApplicaton是整个应用的管理中心,这里创建了一个初始化了一些springboot基本的配置的对象
/**
* Create a new {@link SpringApplication} instance. The application context will load
* beans from the specified primary sources (see {@link SpringApplication class-level}
* documentation for details. The instance can be customized before calling
* {@link #run(String...)}.
* @param resourceLoader the resource loader to use
* @param primarySources the primary bean sources
* @see #run(Class, String[])
* @see #setSources(Set)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
这里要注意看构造方法,step into进去SpringApplication构造方法里面可以看到构造方法做了一下基础数据的设置:
- 设置资源加载器
- 设置主类
- 设置应用类型
- 设置初始化器
- 设置监听器
- 设置启动类(启动方法mian所在类)
这里我们主要关注设置初始化器和监听器的过程。
这里两个过程调用的是同一个方法getSpringFactoriesInstances,两次调用传了不一样的参数返回了两个不一样的工厂实例集合。
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,