SpringIOC源码解析(6)—— BeanDefinition的注册

简介: BeanDefinitionRegistry负责对BeanDifinition的注册,其中的方法:

文章目录


BeanDefinitionRegistry负责对BeanDifinition的注册,其中的方法:


/**
 * 往注册表中注册一个新的 BeanDefinition 实例
 */
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException;
/**
 * 移除注册表中它注册的 BeanDefinition 实例
 */
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;


/**
 * 从注册表中取得指定的BeanDefinition 实例
 */
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
 * 判断 BeanDefinition 实例是否在注册表中(是否注册)
 */
boolean containsBeanDefinition(String beanName);


我在Spring专栏的之前的文章中曾经写过,DefaultListableBeanFactory继承了BeanDefinitionRegistry

4.png


同时它里面还有个beanDefinitionMap

/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);


所谓的注册就是往beanDefinitionMap中存储相应的<key,value>




再回到DefaultBeanDefinitionDocumentReader的processBeanDefinition方法


5.png


  注册方法传入两个参数,BeanDefinition的包装实例和Registry实例,getRegistry返回的是AbstractBeanDefinitionReader中的成员变量:

@Override
public final BeanDefinitionRegistry getRegistry() {
   return this.registry;
}

接下来进入到registerBeanDefinition中,


public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {
   // Register bean definition under primary name.
   // 将beandefinition及其名字注册到容器里
   String beanName = definitionHolder.getBeanName();
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
   // Register aliases for bean name, if any.
   // 如果存在别名则逐个注册进容器
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}

再进入到registerBeanDefinition方法里:

6.png


先判断是否是AbstractBeanDefinition实例,由于GenericBeanDefinition就是AbstractBeanDefinition实例,所以肯定要进入 if 里。


 validate是用来校验lookup和replacemethod这两个属性他们对应的重写方法是否存在并且合法。


 接下来就是判重处理了,尝试从注册表里获取BeanDefinition的实例,如果已经存在了会根据容器的配置来决定是否要覆盖掉原先的BeanDefinition,如果允许覆盖则经过各种校验后会覆盖beanDefinitionMap的<key, value>


7.png

  如果原先并没有BeanDefinition的实例,则先判断下容器是否已经开始创建bean实例了(这里是bean不是BeanDefinition,前者依赖后者的创建),注册时会锁住map并把实例put进去


8.png


// 检查是否有同名的BeanDefinition已经在IOC容器中注册
if (existingDefinition != null || containsSingleton(beanName)) {
   // 尝试重置所有已经注册过的BeanDefinition的缓存,包括BeanDefinition
   // 的父类以及合并的beanDefinition的缓存,所谓的合并BeanDefinition
   // 指的的有parent属性的beandefinition,该BeanDefinition会把parent的
   // BeanDefinition属性合并在一块
   resetBeanDefinition(beanName);
}


resetBeanDefinition是个递归调用的过程,比如本次更新A,而B的parent是A,则B也需要做重置,和B相关的包括B原先合并出来的属性,Bean的单例,以及Bean的后置器处理也都需要去做重置,B变化之后也要看看有没有把B当做parent的,也要做相应操作…

相关文章
|
1天前
|
算法 Java Go
ArrayList源码解析
ArrayList源码解析
5 1
|
7天前
|
缓存 Java 开发者
10个点介绍SpringBoot3工作流程与核心组件源码解析
Spring Boot 是Java开发中100%会使用到的框架,开发者不仅要熟练使用,对其中的核心源码也要了解,正所谓知其然知其所以然,V 哥建议小伙伴们在学习的过程中,一定要去研读一下源码,这有助于你在开发中游刃有余。欢迎一起交流学习心得,一起成长。
|
12天前
|
SQL 缓存 Java
|
12天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
14天前
|
安全 Java Shell
Android13 adb input 调试命令使用和源码解析
Android13 adb input 调试命令使用和源码解析
23 0
Mixtral MOE 部分源码解析
Mixtral MOE 部分源码解析
16 0
|
19天前
|
XML Java 数据格式
Spring IOC的源码解析
【4月更文挑战第17天】Spring IOC(控制反转)的核心功能是通过依赖注入(DI)来管理对象的创建和它们之间的依赖关系。要深入理解Spring IOC的工作原理,我们可以从其源码分析入手,特别是关注如何创建和管理Bean以及依赖注入的实现
19 1
|
20天前
|
机器学习/深度学习 存储 C语言
NumPy源码解析:实现原理探究
【4月更文挑战第17天】本文深入解析NumPy源码,探讨其高效性能背后的实现原理。核心是多维数组`ndarray`,基于同质数据、连续内存分配和形状步幅概念。NumPy利用C语言实现数组管理,通过广播机制允许不同形状数组运算,并借助底层线性代数库实现向量化操作。理解这些机制有助于优化科学计算并应用于其他项目。
|
20天前
ChatGLM3 源码解析(五)
ChatGLM3 源码解析(五)
21 0
|
20天前
yolo-world 源码解析(六)(2)
yolo-world 源码解析(六)
47 0

推荐镜像

更多