详解Spring DI循环依赖实现机制
一个对象引用另一个对象递归注入属性即可实现后续的实例化,同时如果两个或者两个以上的 Bean 互相持有对⽅,最终形成闭环即所谓的循环依赖怎么实现呢属性的互相注入呢?
Spring bean生命周期具体流程如下:
实际与bean实例化及初始化相关的流程如下(单例模式,其他模式不支持循环依赖):
在DefaultSingletonBeanRegistry类中提供获得单例bean的方法getSingleton:
对于Spring循环依赖使用三级缓存实现:一级singletonObjects一级缓存,存储单例对象,Bean 已经实例化,初始化完成;二级earlySingletonObjects,存储 singletonObject,这个 Bean 实例化了,还没有初始化;三级singletonFactories,存储 singletonFactory。
实际上Spring在实例化前提前暴露所有需要实例化的Bean,提供BeanDefinition类专注于保存被识别的bean定义。Spring Bean加载全过程(注解配置) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中详细描述了BeanDefinitionMap的生产过程。
bean定义都有了就剩下实例化,最复杂的莫过于循环依赖,三级缓存具体业务逻辑如下图:
总结: 1)Spring 不⽀持原型 bean 的循环依赖。
2)单例bean通过setXxx或者@Autowired进⾏循环依赖
Spring 的循环依赖的理论依据基于 Java 的引⽤传递,当获得对象的引⽤时,对象的属性是可以延后设置的,但是构造器必须是在获取引⽤之前。Spring通过setXxx或者@Autowired⽅法解决循环依赖其实是通过提前暴露⼀个ObjectFactory对象来完成的,简单来说ClassA在调⽤构造器完成对象初始化之后,在调⽤ClassA的setClassB⽅法之前就把ClassA实例化的对象通过ObjectFactory提前暴露到Spring容器中。
最新文章
- 一起学微软Power BI系列-官方文档-入门指南(5)探索数据奥秘
- location.hash详解
- [Google Guava]学习--缓存cache
- 最长公共子序列模板(LCS)和LICS模板
- 【液晶模块系列基础视频】4.2.X-GUI图形界面库-画矩形函数简介
- 使用Objective-C的文档生成工具
- lintcode :Integer to Roman 整数转罗马数字
- 基于Qt的简单计算器
- AccountManager使用教程
- 查看文章strncpy()功能更好的文章
- GNU Make 学习系列一:怎样写一个简单的Makefile
- Ubuntu iptalbes 保存配置
- ASP.NET ValidationGroup 属性和CssClass 属性
- node.js 学习随笔
- 重新编译Linux内核必要性及其准备工作
- koa generator
- gradle修改apk包名和apk文件名
- Python开发——数据类型【列表】
- pthread_cond_wait和pthread_cond_signal以及互斥变量的使用情况
- day10:vcp考试