通过断点调试,阅读源码查看SpringBoot的启动原理,启动过程分为创建对象和运行。这里介绍启动时,SpringBoot的创建对象的过程。
1. 启动流程
从main方法出设置断点,然后debug运行
/image-20200729153624362.png)
调用SpringApplication的静态方法run,然后,对参数再包装再次调用重载run方法
/image-20200729153845855.png)
调用SpringApplication的静态方法run,使用构造函数生成对象
/image-20200729153942629.png)
主要流程:使用SpringApplication的静态方法,创建对象,执行run方法:
- 创建
SpringApplication对象 - 执行
SpringApplication对象的run方法
2. 创建SpringApplication对象
前面首先是通过SpringApplication的静态方法,new出对象再执行run,这里查看创建SpringApplication对象时做了哪些事情
首先是new的过程中显示对类的属性初始化,然后在构造器中调用SpringApplication重载的构造器
/image-20200729160142458.png)
进入重载的构造器中:
1 | public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { |
2.1 检查是不是web应用
调用WebApplicationType的静态方法判断当前应用是不是web应用
/image-20200729162148263.png)
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) { |
/image-20200729164241607.png)
上面类加载器搜索的路径FACTORIES_RESOURCE_LOCATION为:
1 | public final class SpringFactoriesLoader { |
可以看出他是从类路径下META-INF/spring.factories搜索所有ApplicationContextInitializer
2.2.3 通过names创建初始化器,排序返回
/image-20200729170931608.png)
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) { |
/image-20200729170513634.png)
这里的FACTORIES_RESOURCE_LOCATION=”META-INF/spring.factories”
1 | public final class SpringFactoriesLoader { |
即从类路径”META-INF/spring.factories”获取所有的监听器
2.3.3 根据names创建监听器,排序返回
同样调用createSpringFactoriesInstances()创建实例
/image-20200729171246665.png)
2.4 从所有的配置类中找到主配置类
1 | public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { |
到这里就完成了SpringBoot启动时创建对象的过程,通过创建出的这个对象,执行它的run()方法。参见:SpringBoot启动原理(运行)
- 本文作者: zicair
- 本文链接: https://zicair.github.io/2020/07/29/SpringBoot启动原理(创建)/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!
