单例(创建)

<think>我们正在讨论Spring框架中创建Bean的过程。根据引用内容,Spring通过三级缓存机制来解决循环依赖问题,并确保Bean只创建一次。创建过程包括实化、填充属性和初始化等步骤。</think>### Spring Framework 如何创建 Bean 在 Spring 框架中,创建 Bean 的核心流程如下(基于三级缓存机制): 1. **尝试从缓存获取** Spring 首先检查三级缓存(按顺序): - `singletonObjects`(一级缓存):存储完全初始化的 Bean - `earlySingletonObjects`(二级缓存):存储提前暴露的原始 Bean - `singletonFactories`(三级缓存):存储 Bean 的 `ObjectFactory` 2. **实化 Bean** 若缓存未命中,则: - 通过反射调用构造函数创建 Bean 实(此时对象尚未完成依赖注入) - 将原始对象包装为 `ObjectFactory` 并存入三级缓存(解决循环依赖)[^1] 3. **属性填充** - 解析 `@Autowired` 等依赖关系 - 若依赖的 Bean 不存在,触发依赖 Bean 的创建流程 - 循环依赖解决方案:通过三级缓存获取提前暴露的对象[^1][^3] 4. **初始化** - 调用 `@PostConstruct` 方法 - 执行 `InitializingBean.afterPropertiesSet()` - 应用 `BeanPostProcessor` 的后置处理 5. **完成创建** - 将完整 Bean 移入一级缓存 `singletonObjects` - 清理三级缓存中的临时对象 - 记录状态:`this.singletonsCurrentlyInCreation.remove(beanName)`[^3] ```java // 简化版创建流程(AbstractAutowireCapableBeanFactory) protected Object doCreateBean(String beanName) { // 1. 实化 BeanWrapper instance = createBeanInstance(beanName); // 2. 提前暴露引用(解决循环依赖) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, instance)); // 3. 属性注入 populateBean(beanName, instance); // 4. 初始化 initializeBean(beanName, instance); // 5. 注册完整Bean registerSingleton(beanName, instance.getWrappedInstance()); } ``` ### 关键设计要点 1. **注册表** 通过 `DefaultSingletonBeanRegistry` 维护缓存映射: ```java private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(); // 一级缓存 private final Map<String, Object> earlySingletonObjects = new HashMap<>(); // 二级缓存 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(); // 三级缓存 ``` 2. **循环依赖处理** 当 Bean A 依赖 Bean B,且 Bean B 也依赖 Bean A 时: - A 创建半成品对象后存入三级缓存 - B 创建时通过 `ObjectFactory.getObject()` 获取 A 的代理 - B 完成创建后注入 A,A 继续完成初始化[^1][^3] 3. **线程安全保证** - 使用 `synchronized` 块保护缓存操作 - 通过 `singletonsCurrentlyInCreation` 集合跟踪创建中的 Bean > **性能提示**:Spring 的模式通过复用 Bean 实减少对象创建开销,但需注意避免有状态的 Bean 引发线程安全问题[^2][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不仅仅是寻找

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值