Spring Boot-17-配置类解析逻辑

上文中,了解了配置类解析的一个入口和整体的流程,本文来详细的了解一下配置类解析的逻辑,也就是上文说的 ConfigurationClassPostProcessor.processConfigBeanDefinitions() 这个方法中 do-while 循环的 do 部分,看一下他具体是如何处理的

image

源码跟踪

重点是这里的 parse() 方法,进入看一下具体处理逻辑

ConfigurationClassParser$parse

image

这里做个类型判断,通常情况都是 AnnotatedBeanDefinition 类型的, 进入下面的 parse() 方法看一下

image

这里 3 个重载方法都一样,都是 new 了一个 ConfigurationClass 对象,然后调用了 processConfigurationClass() 这个方法, 然后以 AnnotatedBeanDefinition 类型为例,看看 ConfigurationClass 对象中都有哪些属性

image

ConfigurationClassParser$processConfigurationClass

然后看一下 processConfigurationClass 这个方法

image

这里有个比较重要的集合是 configurationClasses ,是一个 Map 集合, processConfigurationClass() 方法处理完毕后,会把当前类放进去
这个方法里面先调用了一个 asSourceClass() 这个方法,然后是一个 do-while 循环,里面又调用了 doProcessConfigurationClass() 方法

ConfigurationClassParser$asSourceClass

先来看一下这个 asSourceClass() 方法,如下

image

最终是返回了一个 SourceClass 对象, 构造方法如下

image

ConfigurationClassParser$doProcessConfigurationClass

返回来再来看一下 doProcessConfigurationClass() 这个方法,如下

image

这里会一次判断是否有这些注解,然后依次处理,具体处理逻辑我们之后再说, 最终会进入一个if判断,如果有父类就返回父类,没有的话,返回 null ,具体的判断逻辑如下:

image

如果有父类,并且符合其他条件,就返回出去,供外面的 do-while 继续循环

最终结束后,parse方法就处理完成了,之后会进入下面的 parser.validate() 方法

ConfigurationClassParser$validate

点进去看一下,具体是如何做的验证

image

继续往下

image

image

验证完成之后,回到 do 方法体内, 会声明一个 configClasses 集合,然后值是 parse 方法解析出来的所有配置类,然后移除掉处理过的,再获得一个 ConfigurationClassBeanDefinitionReader 对象,调用其 loadBeanDefinitions() 方法

ConfigurationClassBeanDefinitionReader$loadBeanDefinitions

image

这个方法的主要作用就是,加载所有的 BeanMethod , 然后将返回值注册到容器中, 这就是为什么我们用 @Bean 注解修饰的方法返回的对象会注册到 Spring 容器中

处理完成之后添加到一个处理过 alreadyParsed 的集合中,然后把 candidates 结合清空

之后是一个判断详细的看一下这个判断的具体作用

image

这个判断的作用就是处理 @Bean 注入的新的 BeanDefinition ,之后继续 do-while 循环,直到没有新的 BeanDefinition

以上就是这个 do-while 循环中做的全部事情, 其实重点的处理逻辑都在 ConfigurationClassParser$doProcessConfigurationClass 这个方法中, 下文中会详细分析

总结

最后把这个 do-while 中的逻辑做一个总结

配置类的解析入口是在 ConfigurationClassPostProcessor$processConfigBeanDefinitions() 这个方法的 do-while 循环体当中, 循环终止的条件是配置类没有向 BeanFactory 中注册新的 BeanDefinition

然后整个 do-while 循环的流程图如下:

image

然后 parse() 方法的逻辑:

image

最后 doProcessConfigurationClass() 方法中的处理逻辑

image