通过断点调试,阅读源码查看SpringBoot的启动原理,启动过程分为创建对象和运行。这里介绍启动时,SpringBoot的创建对象的过程。
1. 启动流程
从main方法出设置断点,然后debug运行
调用SpringApplication的静态方法run,然后,对参数再包装再次调用重载run方法
调用SpringApplication的静态方法run,使用构造函数生成对象
主要流程:使用SpringApplication的静态方法,创建对象,执行run方法:
- 创建
SpringApplication
对象 - 执行
SpringApplication
对象的run方法
2. 创建SpringApplication
对象
前面首先是通过SpringApplication
的静态方法,new出对象再执行run,这里查看创建SpringApplication
对象时做了哪些事情
首先是new的过程中显示对类的属性初始化,然后在构造器中调用SpringApplication
重载的构造器
进入重载的构造器中:
1 | public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { |
2.1 检查是不是web应用
调用WebApplicationType
的静态方法判断当前应用是不是web应用
2.2 设置初始化器
1 | public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { |
设置初始化器先是通过getSpringFactoriesInstances(ApplicationContextInitializer.class)获得结果,然后将结果保存到this.initializers
1 | public void setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers) { |
2.2.1 调用getSpringFactoriesInstances(ApplicationContextInitializer.class)
1 | private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) { |
1 | private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { |
2.2.2 获取names
1 | public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader){ |
上面类加载器搜索的路径FACTORIES_RESOURCE_LOCATION
为:
1 | public final class SpringFactoriesLoader { |
可以看出他是从类路径下META-INF/spring.factories搜索所有ApplicationContextInitializer
2.2.3 通过names创建初始化器,排序返回
2.3 设置监听器
1 | public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { |
设置监听器和设置初始化器的步骤类似,调用getSpringFactoriesInstances(ApplicationListener.class)方法,然后将得到的结果存在this.listeners中
1 | public void setListeners(Collection<? extends ApplicationListener<?>> listeners) { |
2.3.1 调用getSpringFactoriesInstances(ApplicationListener.class)
1 | private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) { |
1 | private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { |
2.3.2 获取names
1 | public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader){ |
这里的FACTORIES_RESOURCE_LOCATION=”META-INF/spring.factories”
1 | public final class SpringFactoriesLoader { |
即从类路径”META-INF/spring.factories”获取所有的监听器
2.3.3 根据names创建监听器,排序返回
同样调用createSpringFactoriesInstances()创建实例
2.4 从所有的配置类中找到主配置类
1 | public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { |
到这里就完成了SpringBoot启动时创建对象的过程,通过创建出的这个对象,执行它的run()方法。参见:SpringBoot启动原理(运行)
- 本文作者: zicair
- 本文链接: https://zicair.github.io/2020/07/29/SpringBoot启动原理(创建)/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!