阿古达芝麻开门 - 博客园

在Springboot项目下面是如何组装Bean的(中)-BeanDefinitions加载

ConfigurationClassPostProcessor#parser.parse(candidates)执行完成之后,parser对象中的configurationClasses从0个变成了45个,所以可以知道parser.parse(candidates)是根据传入的启动类找到了某些配置类

图片

现在来看看parse方法,第一个解析的就是启动类:

图片

在doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)这个方法中:

  1. processMemberClasses(configClass, sourceClass);解析内部类;

  2. Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);解析@ComponentScan注解

  3. processImports(configClass,sourceClass,getImports(sourceClass), true);递归解析@Import注解,下图是启动类找到的三个需要Import的配置类
    图片

    下面是两处递归处理:

    图片

    图片

    这部分代码很重要,至今还有点雾里看花,一堆循环,一堆递归的...

  4. processPropertySource(propertySource);解析@PropertySource注解

  5. Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);解析标注有@Bean的方法

  6. processInterfaces(configClass, sourceClass);递归解析所有改bean实现的接口

  7. sourceClass.getMetadata().getSuperClassName();解析父类

  8. 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的加载过程主要有两个阶段:

    1. parser.parse识别是否Configuration Bean

    2. loadBeanDefinitions(configClasses)加载并解析,存储到beanDefinitionMap中


      更多了解请关注一米源码公众号并回复SpringBoot或https://itproject-manager.com/

posted @   阿古达芝麻开门  阅读(324)  评论(0编辑  收藏  举报
编辑推荐:
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示