Springboot 是从 Application类的 main方法开始运行的,通过运行SpringApplication的run方法,将要运行的类放入参数中,开始运行的。因此我们从这里开始跟踪代码来学习Springboot的启动过程中都做了什么事情。
Springboot的入口类:
下面来看实际运行的SpringApplication类的run方法的源码:
先是调用了 1 处的run方法,然后调用了2处的run方法,这两个方法都有两个参数分别是加载的主要资源类和传递过来的参数。
可以看到 在2处的调用中进行了两步:实例化一个SpringApplication,调用该实例化对象的run方法。
我们先来看第一部分:实例化一个SpringApplication。
在第一个构造函数中调用了第二个构造函数。
前三步都好理解,我们看看第四步的源码:
就是根据类路径下是否有对应项目类型的类推断出不同的应用类型。
第五步中 ApplicationContextInitializer类的作用通过类上的注释可以知道:
这个类就是进行初始化的。
接下来看看 setInitializers 方法:
就是设置应用上下文初始化器的集合。
loadFactoryNames方法如下:
其中 FACTORIES_RESOURCE_LOCATION :
就是查找工厂的地址,有可能出现在多个jar文件中。
其中的 loadSpringFactories方法返回一个Map,然后工厂的类名就是Map的key,通过key获取相应工厂的实现类名字列表。
下面看loadSpringFactories方法的源码:
来看一个实际地配置:
Spring-boot-autoconfigure-2.1.0-RELEASE-sources.jar 的 META-INF/spring.factories文件中 initializer的配置:
好了,loadFactoryNames方法就先看到这里。
接下来继续查看 createSpringFactoriesInstances 方法:
就是将获取到的 initializers 都实例化了,在getSpringFactoriesInstances方法的最后排个序然后返回。
继续看第六步设置监听:
看看 ApplicationListener是什么:
然后 getSpringFactoriesInstances方法又实现了监听器的实例化。
Spring-boot-autoconfigure-2.1.0-RELEASE-sources.jar 的 META-INF/spring.factories文件中 listener的配置:
第七步:设置mainApplicationClass:
这个推断主入口类的方法有点特别,构造了一个运行时异常,然后遍历异常栈中的方法名,找到 main方法名然后返回这个main方法的类的全限定名。
好了第一部分实例化SpringApplication的代码就先跟到这里,下面先来个小结。
小结
从实例化SpringApplication的七步中可以看到:
设置了资源加载器,这里是null;判断了primarysource不能为空;初始化了主要加载类集合,并去重,从这里可以看出能够加载多个类进来;推断当前应用的类型;设置并实例化初始化器;设置并实例化监听器集合;推断并设置主应用类。
这些步骤中设置这些东西的意义现在还不知道,等下面分析run方法的时候也许可以揭秘。