
深入理解Spring循环依赖解决机制
86KB |
更新于2024-09-01
| 170 浏览量 | 举报
收藏
"简单了解Spring循环依赖解决过程"
在Spring框架中,循环依赖指的是两个或多个bean之间形成相互依赖的关系,导致它们无法正常初始化。Spring提供了几种机制来处理这种问题,主要集中在属性的循环依赖上,因为构造器的循环依赖在Java中通常是无法解决的,会导致`StackOverflowError`。下面我们将深入探讨Spring如何解决属性循环依赖。
1. **单例bean的三级缓存**
Spring使用三级缓存来处理单例bean的循环依赖问题。这三级缓存分别是:
- `SingletonObjects`: 存储完全初始化好的bean,也就是已经完成了依赖注入的对象。
- `EarlySingletonObjects`: 存储的是早期暴露的bean,此时bean只是实例化了,但还没有完成依赖注入。
- `SingletonFactories`: 存储bean的工厂,可以用来创建bean实例。
2. **实例化过程**
当Spring遇到一个bean的实例化请求时,会按照以下步骤进行:
- **预实例化**: 对于单例bean,Spring会在容器启动时进行预实例化,这样可以尽早发现循环依赖。
- **创建Bean实例**: 使用`DefaultListableBeanFactory`的`createBean()`方法开始实例化过程。
- **填充属性值**:
- **检查早起暴露**: 如果bean已经存在于`EarlySingletonObjects`中,那么它会被直接返回,从而打破循环依赖。
- **如果没有早起暴露**: Spring会创建一个代理,将这个未初始化的bean放入`SingletonFactories`缓存,然后尝试继续实例化其他依赖。
- **依赖注入**: 此时如果遇到了循环依赖,Spring会从`SingletonFactories`中取出对应的bean工厂,使用工厂创建一个代理对象,将这个代理对象注入到依赖者中,从而避免了直接依赖未初始化的bean。
3. **依赖注入阶段**
- **填充属性**: 在依赖注入过程中,Spring使用了` Aware`接口(如`BeanFactoryAware`、`ApplicationContextAware`等)让bean可以感知到容器,从而在必要时获取其他bean。
- **属性注入**: 通过`PropertyPlaceholderConfigurer`、`AutowiredAnnotationBeanPostProcessor`等后处理器完成属性的自动装配。
- **最终初始化**: 所有依赖注入完成后,bean才会被添加到`SingletonObjects`缓存中,成为完全初始化的bean。
4. **原型bean与循环依赖**
对于原型(prototype)作用域的bean,Spring不会尝试解决循环依赖,因为原型bean每次请求都会创建一个新的实例,这样的场景下循环依赖通常不是问题。
5. **注意事项**
- Spring的循环依赖解决方案只适用于单例bean,对于 prototype 或其他作用域的bean,开发者需要自行处理循环依赖问题。
- Spring不支持在构造器中的循环依赖,因为它无法在构造阶段预测和解决依赖关系。
- Spring的循环依赖解决方案依赖于AOP代理,因此如果关闭了AOP,循环依赖可能无法正确处理。
Spring通过其独特的三级缓存机制,以及在bean生命周期的不同阶段进行干预,有效地解决了单例bean的循环依赖问题。然而,设计时应尽量避免循环依赖,以提高代码的可读性和可维护性。
相关推荐





















weixin_38526979
- 粉丝: 6
最新资源
- Hackathon前端项目:SplatMap前端开发指南
- Olist-Frontend挑战赛:女性黑客奥利斯特引领技术教程
- 利用amqp.node.amqplib实现RabbitMQ的管道和过滤器
- Flasky:如何搭建一个基本的Flask应用
- SafePort: 用户友好的端口扫描工具教程与代码下载
- Horse Octet Stream中间件应用与安装指南
- 赛朋克大学应用部署指南
- Ansible iRODS预配器:设置iRODS群集指南
- Erick Wendel的SemanaJS-expert JavaScript课程解析
- 掌握并行技术实现GPT2/3模型的Python开发
- 基于Docker的Chicago Boss Web框架部署
- Netmiko库简化Paramiko与网络设备SSH连接流程
- BaySeg:基于贝叶斯推理的空间数据集无监督聚类Python库
- Kaggle获奖空气质量预测模型:随机森林代码免费下载
- 高仿电商平台的 RecyclerView 购物车分组功能
- Laravel Block Bots: 利用Redis防止不良爬虫和流量滥用
- 基于HTML/CSS/Javascript的Instagram网络版项目教程
- IA-UNAM天文学研究所Python讲座完整资料
- JC的快照区域关闭通知
- 8寸晶圆代工成本上涨,功率与电源IC供应链压力增大
- 基于Django的空气质量指数(AQI)分析应用开发
- React项目实践:掌握自定义模态与分页技巧
- Matlab软件包xtractoMatlab:提取海洋卫星数据的利器
- 官方DPFields扩展套件:Joomla自定义字段的开源解决方案