1、SpringApplication实例的初始化创建

查看SpringApplication实例对象初始化创建的源码信息,核心代码具体如下

1、 进入 SpringApplication方法

image.png

2、首先是进入带参数的构造方法

image.png
SpringApplication 实例化过程,首先是进入带参数的构造方法,最终回来到两个参数 的构造方法。

3、构建和初始化SpringApplication

image.png

开始需要对此4项 进行 重点分析。

4、第一项,进入deduceFromClasspath看如何获取环境

image.png

4.1、第一项的具体获取环境源码

image.png

返回类型是WebApplicationType的枚举类型, WebApplicationType 有三个枚举,三个枚举的解释如 其中注释 具体的判断逻辑如下:
WebApplicationType.REACTIVE classpath下存在 org.springframework.web.reactive.DispatcherHandler WebApplicationType.SERVLET classpath下存在javax.servlet.Servlet或者 org.springframework.web.context.ConfigurableWebApplicationContext
WebApplicationType.NONE 不满足以上条件。

第一项的说明如下: this.webApplicationType=WebApplicationType.deduceFromClasspath()用于判断当前webApplicationType应用的类型。deduceFromClasspath()方法用于查看Classpath类路径下是否存在某个特征类,从而判断当前webApplicationType类型是SERVLET应用(Spring5之前的传统MVC应用)还是REACTIVE应用(Spring5开始出现的WebFlux交互式应用)。

5、第二项,进入getSpringFactoriesInstances方法

image.png

5.1、继续调用重载方法

image.png

5.2、进入getSpringFactoriesInstances方法

image.png

5.3、通过debug模式,进入loadFactoryNames方法

image.png

5.3.1、进入loadFactoryNames方法并运行

然后 运行 一行,看其获取的 factoryTypeName
loadFactoryNames() 这个方法很重要,这个方法是spring-core中提供的从META-INF/spring.factories中获取指定的类 (key)的同一入口方法。 在这里,获取的是key为 org.springframework.context.ApplicationContextInitializer 的类。
image.png

5.3.2、继续进入loadSpringFactories方法

image.png

5.3.2.1、看其如何加载配置文件

image.png

5.3.2.2、获取指定路径,然后通过loadProperties加载

image.png

5.3.2.3、最后返回的加载结果

image.png

ApplicationContextInitializer 是Spring框架的类, 这个类的主要目的就是在 ConfigurableApplicationContext 调用refresh()方法之前回调这个类的initialize方法。 通过 ConfigurableApplicationContext 的实例获取容器的环境Environment,从而实现对配置文件的 修改完善等工作

第二项的说明如下: this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class))
用于SpringApplication应用的初始化器设置。在初始化器设置过程中,
使用Spring类加载器SpringFactoriesLoader从 META-INF/spring.factories 类路径下的META-INF下的spring.factores文件中获取所有可用的应用初始化器类ApplicationContextInitializer

5.3.3、根据传回的参数去创建对应的工厂

image.png

5.3.3.1、创建工厂的源码

image.png

5.3.4、对返回的实例进行排序

其实也就是5.2中看到的第三个方法 sort

6、第三项,进入getSpringFactoriesInstances方法

这次和上面第二项走的流程是一样的。只不过此次获取的是简体器
image.png
(整个流程按第5点的全部走即可)

6.1、最后返回的执行结果

image.png

第三项的说明如下:
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class))用于SpringApplication应用的监听器设置。监听器设置的过程与上一步初始化器设置的过程基本一样,
也是使用SpringFactoriesLoader从META-INF/spring.factories类路径下的META-INF下的spring.factores文件中获取所有可用的监听器类ApplicationListener

7、第四项,进入deduceMainApplicationClass方法

image.png

7.1、右键选中Evaluate来试看一下返回结构

(以前可能是先把流程走了,看返回结果,现在直接右键来查看,工具用起来很顺手啊)
image.png

7.1.1、具体获取main方法的全限定类名

image.png

第四项的说明如下:
this.mainApplicationClass=this.deduceMainApplicationClass()
用于推断并设置项目main()方法启动的主程序启动类

从上述源码可以看出,SpringApplication的初始化过程主要包括4部分
关于 SpringApplication 类的构造过程,到这里就梳理完了。纵观 SpringApplication 类的实例化过程,可以看到,合理的利用该类,就能在spring容器创建之前做一些预备工作,和定制化的需 求
比如自定义SpringBoot的Banner,
比如自定义事件监听器,
再比如在容器refresh之前通过自定义 ApplicationContextInitializer 修改配置
一些配置或者获取指定的bean都是可以的