在Springboot项目下面是如何组装Bean的(中)-BeanDefinitions加载
ConfigurationClassPostProcessor#parser.parse(candidates)执行完成之后,parser对象中的configurationClasses从0个变成了45个,所以可以知道parser.parse(candidates)是根据传入的启动类找到了某些配置类
现在来看看parse方法,第一个解析的就是启动类:
在doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)这个方法中:
-
processMemberClasses(configClass, sourceClass);解析内部类;
-
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);解析@ComponentScan注解
-
processImports(configClass,sourceClass,getImports(sourceClass), true);递归解析@Import注解,下图是启动类找到的三个需要Import的配置类
下面是两处递归处理:
这部分代码很重要,至今还有点雾里看花,一堆循环,一堆递归的...
-
processPropertySource(propertySource);解析@PropertySource注解
-
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);解析标注有@Bean的方法
-
processInterfaces(configClass, sourceClass);递归解析所有改bean实现的接口
-
sourceClass.getMetadata().getSuperClassName();解析父类
-
return null;跳出do while循环,完成一个配置类的识别,并放到configurationClasses中:
parser.parse(candidates)处理完成后找到了45个配置类:
------^_^------漂亮的分隔符------^_^------
找到了相关配置类之后循环交个ConfigurationClassBeanDefinitionReader去解析:
在ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass这个方法里面:
a. registerBeanDefinitionForImportedConfigurationClass: 主要判断bean的scope, 给bean取名,是否延迟加载,是否启动类,依赖的bean,解析完会先注册到beanDefinitionMap.
b. loadBeanDefinitionsForBeanMethod: 这里是解析当前类是否有@Bean注解的方法,因为这样也是可以注册一个bean的,解析完成同样放到beanDefinitionMap
c. loadBeanDefinitionsFromImportedResources: 解析@ImportResource注解(不常用,忽略)
d. loadBeanDefinitionsFromRegistrars: 解析需要扫描的包路径,最终会交给AutoConfigurationPackages#register去完成,解析完成同样放到beanDefinitionMap(不过此时放的并不是具体的某个Class的BeanDefinition,而是AutoConfigurationPackages对象)
DefaultListableBeanFactory#registerBeanDefinition,BeanDefinition解析完成之后,最后会把解析结果放到beanDefinitionMap中
下图中的this.reader.loadBeanDefinitions(configClasses);执行完成后
可以看到beanFactory中已经存在所有的BeanDefinition了:
总结:BeanDefinition的加载过程主要有两个阶段:
-
parser.parse识别是否Configuration Bean
-
loadBeanDefinitions(configClasses)加载并解析,存储到beanDefinitionMap中
更多了解请关注一米源码公众号并回复SpringBoot或https://itproject-manager.com/
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)