AutoConfigurationImportSelector 到底怎么初始化
1. 前言
我们知道,在spring中,一般的实现ImportSelector接口,然后重写selectImports方法,就可以使用到spring的SPI技术,加载spring.factories中配置的org.springframework.boot.autoconfigure.EnableAutoConfiguration.EnableAutoConfiguration
的类。
抱着测试的心态,给@SpringBootApplication
的注解上实现的SelectorAutoConfigurationImportSelector#selectImports
打上断点测试,这一测试,不得了,心态崩了,debug没进去。Demo有问题?换上开发的项目,还是没有进debug,难道是大家说的有问题?不行,我这暴脾气忍不了,要一探究竟。
Note: 本文基于SpringBoot:2.3.0.RELEASE。一般解析写在代码的注释上
2. 序列图
先摆上debug的时序图,方法返回没画(太丑,me嫌弃,有个大概了解一下就行)
3. 代码分析
代码太多,跳过了部分简单代码,然后挑关键点
说。
1. 从这
SpringApplication#refresh
当入口
2. 进入
org.springframework.context.support.AbstractApplicationContext#refresh
方法
3. 进入
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
,这有关键点,就是生成的postProcessorNames
Debug图片
我们通过Debug可以看出,currentRegistryProcessors
中放的是ConfigurationClassPostProcessor
的Bean对象,接着就调用了invokeBeanDefinitionRegistryPostProcessors
方法并传入ConfigurationClassPostProcessor
。
4. 接着进入
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
方法
Debug图片
通过图片,可以看出,candidates
只有一个,那就是启动类SpringDemoApplication(测试项目的启动类).
5. 进入
org.springframework.context.annotation.ConfigurationClassParser#parse()
方法,开始解析启动类。
6. 接下来进入
org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClass
方法。
7. 进入
org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
方法,直接分析代码.
getImports(sourceClass)
这个方法是递归调用,找到注解Import中的值。 放个Debug图给大家瞅一下。CustomizedImportSelector
是我自己测试的,
8. 进入
org.springframework.context.annotation.ConfigurationClassParser#processImports
方法,核心来了,就是问题的关键,到底是怎么使用SpringSPI的
9.
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#handle
方法
自此,我们分析完AutoConfigurationImportSelector
在第一遍解析完后,被放在哪,那接下来就是如何解析了。激动人心的时刻来了。那就是在ConfigurationClassParser#parse()
中执行的代码了this.deferredImportSelectorHandler.process();
10.
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#process
代码
11.
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#register
代码
12.
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports
方法,SpringSPI的调用点
13.
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping#getImports
14.
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process
方法
自此,我们的代码分析结束,发现AutoConfigurationImportSelector.class
在SpringBoot启动中,并不是调用的selectImports方法,而是直接调用的getAutoConfigurationEntry
方法
4. 总结
SpringBoot在启动中,AutoConfigurationImportSelector
在被加载中,调用的不是selectImports方法, 而是直接被调用了getAutoConfigurationEntry方法。 骚年,你可长点心吧!
感谢支持。推荐!!!
课外文件,解忧星球
|
版权声明: 本文为 InfoQ 作者【编号94530】的原创文章。
原文链接:【http://xie.infoq.cn/article/1c2bc90f1b22e2d5092723691】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论