【SpringBoot】SpringBoot源码解析第五章 SpringBoot的beanDefinition收集过程

 e246a1dda09849a5a89535a62441565d.png

【SpringBoot】SpringBoot源码解析第一章 SpringBoot的构造方法-CSDN博客

【SpringBoot】SpringBoot源码解析第二章 SpringBoot的run方法-CSDN博客

【SpringBoot】SpringBoot源码解析第三章 SpringBoot的自动化配置-CSDN博客

【SpringBoot】SpringBoot源码解析第四章 SpringBoot的bean接口-CSDN博客

【SpringBoot】SpringBoot源码解析第五章 SpringBoot的beanDefinition收集过程-CSDN博客

【SpringBoot】SpringBoot源码解析第六章 SpringBoot的getBean方法-CSDN博客

【SpringBoot】SpringBoot源码解析第七章 SpringBoot的感悟-CSDN博客

上一章我们分析了SpringBoot的bean接口,这一章我们来分析SpringBoot的beanDefinition收集过程

参考源码:<spring.boot.version>2.3.12.RELEASE</spring.boot.version>

目录

1、BeanDefinition介绍

2、BeanDefinition收集过程

3、总结

1、BeanDefinition介绍

BeanDefinition包含了bean的全限定名、父类全限定名、元数据等属性,将bean的所有信息都囊括在内,为之后生产bean做好了准备

2、BeanDefinition收集过程

我们在第二章的1.3.1小节里提到过invokeBeanFactoryPostProcessors方法

【SpringBoot】SpringBoot源码解析第二章 SpringBoot的run方法-CSDN博客

invokeBeanFactoryPostProcessors方法会调用BeanFactoryPostProcessors接口实现类的postProcessBeanFactory方法来操作beanDefinition

调用链:
-> AbstractApplicationContext.refresh
-> invokeBeanFactoryPostProcessors(beanFactory)
-> PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
-> invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
-> postProcessor.postProcessBeanDefinitionRegistry(registry)
-> ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry

--- 分割调用链,避免看的头痛 ---

-> processConfigBeanDefinitions(registry)
-> parser.parse(candidates);
-> parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
-> processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
-> doProcessConfigurationClass(configClass, sourceClass, filter);
-> this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
-> scanner.doScan(StringUtils.toStringArray(basePackages));

我们重点关注最后一个方法:ClassPathBeanDefinitionScanner类的doScan方法;doScan方法会收集指定包下被注解标记过的bean的beanDefinition

调用链:
-> ClassPathScanningCandidateComponentProvider.findCandidateComponents
-> scanCandidateComponents(basePackage)

scanCandidateComponents方法会先遍历包下所有的类文件(resource),然后获取类的元数据阅读器,调用isCandidateComponent方法判断当前类是不是被注解标记的bean,如果是则将元数据阅读器封装成一个ScannedGenericBeanDefinition(ScannedGenericBeanDefinition继承自BeanDefinition)

回到ClassPathBeanDefinitionScanner类的doScan方法,在收集完包下的beanDefinition后,还需要对这些beanDefinition做进一步的加工,将元数据里的信息填充到beanDefinition内

值得一提的还有beanName的获取过程。beanName是通过generateBeanName方法获取的,如果注解中有写beanName,则采用注解里的名称

否则调用decapitalize方法,取首字母小写的类名作为beanName

在加工完BeanDefinition后,会执行registerBeanDefinition方法,将beanName作为key,BeanDefinition作为value存储在一个map中,后续就可以通过beanName从map中获取beanDefinition

3、总结

doScan方法会收集指定包下被注解标记过的bean的beanDefinition,并将beanDefinition按beanName存储为map供后续使用

下一章我们来分析SpringBoot的getBean方法,看看getBean方法是如何使用这些beanDefinition的

【SpringBoot】SpringBoot源码解析第六章 SpringBoot的getBean方法-CSDN博客

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值