invokeBeanFactoryPostProcess
2024-09-06 14:57:30 0 举报
IOC源码
作者其他创作
大纲/内容
文本
deferredlmports.sort排序
Y
解析@Conditional
importCandidates
Loop
循环从所有BeanDefinition拿到配置类并且标记:CONFIGURATION_CLASS_ATTRIBUTE属性分2种:1.full完整配置类@configuration2.lite精简版配置类:@Component@ComponentScan@ @lmportResource @Bean
3
refresh
Loop
process()
@Import-importBeanDefinitionRegistrars
实现延时ImportSelector
经过一些列的解析(scope、lazy、DependsOn等.)
Resource[] resources=getResourcePatternResolver0.getResources(\"classpath*:com/tuling/iocbeanlifecicle/** /*.class\");
SpringBoot逻辑AutoConfigurationlmportSelector implementsDeferredImportSelector
排序
getAutoConfigurationEntry0获得所有自动装配类
调用自定义的实现了FactoryRegistryPostProcessor接口
没实现普通ImportSelector
ConfigurationClassimportBeanDefinitionRegistrars.put
调用实现了BeanFactoryPostProcessor接口
PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
并且实现了Ordered接口
selectlmports
isCandidateComponent
asConfigClass(ConfigurationClass importedBy)new一个ConfigClass 使用importedBy标记是从哪个配置类中@Import进来的
else
解析@Bean
在这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScans注解扫描的包,以及解析@Import等注解。
!candidates.isEmpty()
do
1
将@ComponetScan的信息存到scanner.excludeFilters includeFiltersScopedProxyMode lazyInit ...
selectorinstanceof DeferredImportSelector是否实现接口
此处只把所有@Bean方法读取出来add到Set中,并未解析成BeanDefinition
return null
ClassPathScanningCandidateComponentProvider#scanCandidateComponents()
会在这里解析
excludeFilters
没有实现任何的优先级接口的
[Condition]
Loop basePackages
找到候选BeanDefnitionfindCandidateComponents
configClass
deferredImportSelectors.add
会在解析完配置后调用processDeferredImportSelectors()解析
processConfigBeanDefinitions(registry)
2
会在这理解解析
configClass当作配置类
candidateNames
for
内容:Spring的refresh.invokeBeanFactoryPostProcessors.
解析@Import
加入到集合中,最终返回
并且实现了PriorityOrdered接口
加载已注册的Bean定义的后置处理器也就是之前注册的:this.reader = new AnnotatedBeanDefinitionReader(this); 和注册的配置类从里面找到实现了BeanDefinitionRegistryPostProcessor接口的,也就是我们的ConfigurationClassPostProcessor
此处小细节:会调用ConfigurationClassPostProcessor的postProcessBeanFactory方法将配置类创建CGLIB代理只有full版配置类才会创建cglib代理 虽然我们在指定配置的时候不标注@Configuration也行,所以加不加注解的区别就在这里 那么加了@Configuration和不加有本质上有什么区别的? 当在配置类中一个@Bean 使用方法的方式引用另一个Bean如果不加注解就会重复加载Bean 如果加了@Configuration 则会在这里创建cglib代理,当调用@Bean方法时会先检测容器中是否存在
调用自定义的实现了FactoryRegistryPostProcessor接口和实现了Order接口的
解析@ComponentScan
new ClassPathBeanDefinitionScanner的时候会注册默认的includeFilters其中就包含Component.class
得到当前配置类下所有@Bean方法beanMethods=retrieveBeanMethodMetadata
postProcessors-就一个ConfigurationClassPostProcessor
ConfigurationPhase#REGISTER_BEAN
invokeBeanFactoryPostProcessors
DefaultDeferredlmportSelectorGroup.proces
new ConfigurationClassParser
再次当作配置类解析,如果不是配置类最终会当作普通Bean定义注册
ConfigurationClassParserprocesslmports
registerBeanDefinitionfont color=\"#f44336\
解析我们的配置类
递归处理直到处理为 else configClass
createGroup0.DefaultDeferredImportSelectorGroup
调用创世纪的实现了FactoryRegistryPostProcessor接口和Order接口
getImports(sourceClass)获得当前配置类的@Import注解的导入类
doProcessConfigurationClass
在这里注册
解析配置类
this.reader.loadBeanDefinitions(configClasses);
ClassPathBeanDefinitionScanner#doScan
在这里把之前添加的BeanMethod开始注册为Bean定义
2.创建配置类解析器解析@ComponentScan @lmportBean@lmportResource
@Bean-beanMethods
抽象
selector.selectImports()调用方法返回字符串数组asSourceClasses反射为Class循环处理
getlmportGroup
currentRegistryProcessors.clear()
ConfigurationClassParserprocessImports
Loop :resources
ImportBeanDefinitionRegistrar
循环找出遗漏未解析的配置类
ConfigurationPhase#PARSE_CONFIGURATION每一个@OnConditionalxxx都有不同的验证阶段
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
includeFilters
ConfigurationClassBeanDefinitionReader#loadBeanDefinitions0
else if
用来扫描我们classpath下的标注了@Service @Compent @Respository @Controller
Bean和@lmport白的BeanDefinition在此处注册
候选的BeanDefnition
Loop candidates
ScannedGenericBeanDefinition注册到BeanDefinitionMap中@ComponentScan的扫描算是完成了
@lmport-importedBy
lmportSelector
ConfigurationClass#addBeanMethod()Set<BeanMethod>
processDeferredImportSelectors()
DeferredlmportSelector.getlmportGroup0
加载BD②
loadBeanDefinitionsFromImportedResources()不重要不说了
到此为止所有实现了FactoryRegistryPostProcessor接口的都调用完毕,最主要的工作还是调用了内置ConfigurationClassPostProcessor扫描了Bean定义,和调用自定义的FactoryRegistryPostProcessor注册Bean定义
registerBeanDefinitionbeanDefinitionMapfont color=\"#f5f5f5\
这里只是把ImportBeanDefinitionRegistrar实例缓存起来
loadBeanDefinitionsForBeanMethodconfigClass.getBeanMethods0
else if
可以看出延迟Import和立即Import的解析时机不同,延迟Import会在解析完@Configuration后解析,并且带排序和扩展逻辑(包括SpringBoot)
processPropertySource(propertySource);解析属性资源文件@PropertySource
5.2.x REALEASE
postProcessors-就一个:ConfigurationClassPostProcessor
注册bean定义!
configClass.islmported0从@lmport导入的
ImportSelector
AutoCohfigurationGroup .process
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
获得包下面所有的.class文件
groupsDeferredlmportSelectorGrouping
scanner=new ClassPathBeanDefinitionScanner
AutoConfigurationGroup implements Group
getImports()
调用自定义的实现了FactoryRegistryPostProcessor接口.postProcessBeanFactory方法
return
ComponentScanAnnotationParser#parse
解析@ImportResource
importBeanDefinitionRegistrars
foreach
符合
这里是一条分支,将配置的class注册Bean定义:ConfigurationClassPostProcessor
configClass.getBeanMethods0'
接口
currentRegistryProcessors.add(getBean());创建Bean然后存入到集合中
0 条评论
下一页
为你推荐
查看更多
抱歉,暂无相关内容