Springboot漫游日志(6)
瞅瞅【ApplicationContextInitializer】要加载的实现类。
先把三个spring.factories文件搞出来。
有两个文件中有【ApplicationContextInitializer】
里面都有个斜杠,是表示不换行。
实现类:
- org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
- org.springframework.boot.context.ContextIdApplicationContextInitializer
- org.springframework.boot.context.config.DelegatingApplicationContextInitializer
- org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer
- org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
- org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
- org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
【SpringFactoriesLoader.loadFactoryNames】返回的就是上面这些字符串了。
回到【SpringApplication】的426行。
427行。【createSpringFactoriesInstances】方法,见名知意,创建工厂类的实例。
五个参数:
- type就是【ApplicationContextInitializer】
- parameterTypes是上一个方法传过来的,是一个空的类对象数组。
- classLoader是类加载器,是上一次加载类名称用的那个。
- args是变长参数,也是空的对象数组。
- names就是上面实现类的集合,元素是字符串。
方法在433行。
声明一个同样长度的list集合,遍历names。
第438行,使用【ClassUtils.forName】加载类。
这个类位于:【org.springframework:spring-core】【org.springframework.util.ClassUtils】
看一下注释,这个方法是用来替代Class.forName的,除了原来的Class.forName的功能外,它还能加载基础类型、数组类型、内部类。
实现就不看了,看了头晕,就知道拿到了一个类对象。
回到【SpringApplication】438行。
439行,断言下这个类对象是【ApplicationContextInitializer.class】的实现类。可能是有些项目在自己的spring.factories中加入【ApplicationContextInitializer】的实现类,但是真正的类却没有实现【ApplicationContextInitializer】这接口,所有判断一波?
441行,进去瞅瞅。
先看注释,第一个词搜了一下,是便利的意思。
- 根据给定的构造方法实例化一个类。
- 如果给定的类是非public的,就会被设置成public的。
- 支持无参和默认参数的Kotlin类的实例化。
187行,设置public
188行,如果是kotlin环境,调用对应的方法。
193到203行,先断言args的长度不大于构造方法的参数个数,如果args的参数为null而且是基本类型的话,取基本类型默认值,如果不是就取args的值。然后把得到的参数值传进去,调用构造方法。
这个方法会逮到四个异常。
- Is it an abstract class? 这是一个抽象类?
- Is the constructor accessible? 构造方法是可访问的?
- Illegal arguments for constructor 非法的构造方法参数
- Constructor threw exception 构造方法抛出异常
回到【SpringApplication】441行。
把实例放入list集合,返回集合。
回到【SpringApplication】427行。
428行,来一波排序,返回这个集合。
怎么排序的,后面瞅瞅。