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 类 }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。