frozenBeanDefinitionNames这个集合具有什么功能呢?
下文笔者讲述frozenBeanDefinitionNames集合简介说明,如下所示
frozenBeanDefinitionNames集合简介
`frozenBeanDefinitionNames`是Spring框架中`DefaultlistableBeanFactory`类 中的一个属性 用于存储已经被冻结Bean定义名称 这个集合在Spring容器的生命周期中扮演着重要的角色 确保Bean定义在容器启动后不再被修改 从而提高性能和稳定性。
`frozenBeanDefinitionNames`详细功能和作用
1.功能概述
`frozenBeanDefinitionNames`是一个字符串数组
用于存储所有已经注册到容器中Bean定义名称
且这些名称在容器启动后被标记为“冻结”
其主要功能包括:
-优化性能:
通过将Bean定义名称缓存到一个固定的数组中
避免在运行时频繁地访问和操作原始Bean定义映射表(如 `beanDefinitionMap`)
从而提高容器的性能。
-防止修改:
一旦Bean 定义被冻结
它们的状态就不能再被修改
确保容器的稳定性
-快速查找:
提供一个快速访问Bean定义名称方式
便于在运行时进行各种操作和检查。
2.使用场景
`frozenBeanDefinitionNames`常用于以下场景
-容器初始化完成后:
当 Spring 容器完成所有 Bean 的注册和预处理后
会调用 `freezeConfiguration()` 方法
将 Bean 定义名称冻结
-快速查找 Bean 定义:
在需要遍历或查找 Bean 定义时
直接从`frozenBeanDefinitionNames`中获取名称列表
而无需访问底层`beanDefinitionMap`
-确保配置一致性:
在容器启动后
确保所有 Bean 定义的配置不会被意外修改
从而避免潜在的运行时错误
3.核心方法
(1)`freezeConfiguration()`
-作用:
将容器的配置冻结
表示不再允许对 Bean 定义进行修改。
-实现**:
在`DefaultListableBeanFactory`中
调用此方法会
将`beanDefinitionNames`转换为`frozenBeanDefinitionNames`
清空原始`beanDefinitionNames`列表
例:
public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
this.beanDefinitionNames.clear();
}
(2)`getBeanDefinitionNames()`
-作用:
返回当前容器中所有已注册的 Bean 定义名称。
-实现:
如果配置已被冻结
则直接返回`frozenBeanDefinitionNames`
否则返回`beanDefinitionNames`
例:
public String[] getBeanDefinitionNames() {
return (this.configurationFrozen ?
this.frozenBeanDefinitionNames :
StringUtils.toStringArray(this.beanDefinitionNames));
}
(3)`isConfigurationFrozen()`
-作用:
检查容器的配置是否已被冻结
- 实现:
返回`configurationFrozen`标志的值
例:
public boolean isConfigurationFrozen() {
return this.configurationFrozen;
}
frozenBeanDefinitionNames工作原理
1.注册阶段:
- 在容器启动时
所有的Bean定义会被注册到 `beanDefinitionMap` 和 `beanDefinitionNames` 中。
- `beanDefinitionMap`
是一个`ConcurrentHashMap`
用于存储 Bean 名称和对应`BeanDefinition`对象。
- `beanDefinitionNames`
是一个`LinkedHashSet`
用于存储Bean名称顺序集合
2.冻结阶段:
- 当容器完成所有Bean注册和预处理后
调用 `freezeConfiguration()` 方法
- 在`freezeConfiguration()`方法中
将`beanDefinitionNames`转换为`frozenBeanDefinitionNames`数组
并清空`beanDefinitionNames`
- 设置`configurationFrozen`
标志为`true`
表示配置已被冻结
3.运行阶段:
- 在容器运行期间
`frozenBeanDefinitionNames`
提供了一个只读的、
不可修改Bean 定义名称列表
用于快速访问。
- 任何尝试修改Bean定义
操作都会被检查
如果配置已被冻结,则会抛出异常
frozenBeanDefinitionNames优点
- 性能优化:
- 通过将Bean定义名称缓存到数组中
减少对 `beanDefinitionMap`访问频率
提高容器运行效率。
- 数组的访问速度比集合更快
尤其是在需要频繁遍历Bean名称的情况下
-线程安全:
- 冻结后的 `frozenBeanDefinitionNames`是不可变的
避免多线程环境下的并发修改问题。
-稳定性:
- 冻结机制确保了容器在运行时不会
因为Bean定义的动态修改而导致不一致或错
-快速查找:
- 提供一个快速访问 Bean 定义名称的方式
便于在运行时进行各种操作和检查
frozenBeanDefinitionNames注意事项
-不可修改性:
- 一旦 `frozenBeanDefinitionNames` 被设置
就无法再对其进行修改。
如果需要动态添加或修改 Bean 定义
则需要避免调用`freezeConfiguration()`
- 在某些特殊情况下
可能需要在冻结前完成所有必要的 Bean 定义操作
- 调试信息:
- 在调试 Spring 容器时
可以通过查看`frozenBeanDefinitionNames`
了解容器中所有已注册Bean 名称
- 配置顺序:
- `frozenBeanDefinitionNames`保留Bean定义注册顺序
对于某些需要按顺序处理Bean场景非常重要
例
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class BeanFactoryExample {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 注册 Bean 定义
BeanDefinition beanDef1 = new RootBeanDefinition(MyBean.class);
beanFactory.registerBeanDefinition("myBean1", beanDef1);
BeanDefinition beanDef2 = new RootBeanDefinition(MyBean.class);
beanFactory.registerBeanDefinition("myBean2", beanDef2);
// 冻结配置
beanFactory.freezeConfiguration();
// 获取冻结后的 Bean 定义名称
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String name : beanNames) {
System.out.println("Frozen Bean Definition Name: " + name);
}
// 尝试添加新的 Bean 定义(会抛出异常)
try {
BeanDefinition beanDef3 = new RootBeanDefinition(MyBean.class);
beanFactory.registerBeanDefinition("myBean3", beanDef3);
} catch (IllegalStateException e) {
System.err.println("Cannot modify frozen configuration: " + e.getMessage());
}
}
}
class MyBean {
// 示例 Bean 类
}
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


