Spring容器beanName为啥要存三个地方 beanDefinitionMap、beanDefinitionNames、frozenBeanDefinitionNames?

作者站长头像
站长
· 阅读数 8

不太理解为啥DefaultListableBeanFactory这个类的三个变量 beanDefinitionMap、beanDefinitionNames、frozenBeanDefinitionNames直接用 beanDefinitionMap.keys()代替beanDefinitionNamesfrozenBeanDefinitionNames不可以吗?

回复
1个回答
avatar
test
2024-06-30

1、beanDefinitionMap是一个ConcurrentHashMap,不能保证迭代的顺序,如果直接使用它的keys也就是bean的名称,spring在注入bean的时候,没有办法保证返回的bean名称的顺序与注册的顺序一致,主要是用beanDefinitionMap来存储bean的配置信息,如类名、作用域、依赖关系2、beanDefinitionNames是一个ArrayList,是一个有序列表,就是用来记录bean的注册顺序的,依赖注入时,可以按照beanDefinitionNames的顺序逐个实例化和注入bean3、frozenBeanDefinitionNames是一个String数组,使用数组的原因是因为frozenBeanDefinitionNames在期望情况下不应该发生改变,名字里的frozen(冻结)是spring生命周期里的一个阶段,在该阶段之后,不允许再修改或注册新的 bean 定义,frozenBeanDefinitionNames就是用来记录已经被冻结的bean的名称,调用 registerBeanDefinition 方法注册新的 Bean 定义时,意味着可能会修改已有的 Bean 定义或者添加新的 Bean 定义,因此需要把frozenBeanDefinitionNames 设置为 null,以便在下一次访问时重新计算和更新冻结的 Bean 名称。在 DefaultListableBeanFactory 中,frozenBeanDefinitionNames 的计算和更新是在 getMergedBeanDefinition 方法中进行的。每次调用 getMergedBeanDefinition 方法时,会检查 frozenBeanDefinitionNames 是否为 null,如果是,则重新计算和更新冻结的 Bean 名称。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容