一、什么情况下会出现循环依赖?
二、解决方案
(一)一级缓存:存放完整的Bean实例对象
缺点:一级缓存的方式无法保证多线程下的一级缓存Bean的完整性,可以用加锁的方式来解决此问题。
(二)一级缓存+锁:保证多线程bean创建问题
(三)二级缓存:判断循环是不是依赖
(四)三级缓存:解决AOP代理问题,存放函数接口
bean需要在实例化后进行代理,所以此处存放函数接口,在实例化时执行代理,进行解耦。
三、其他问题
(一)多线程下如何避免获取不完整的bean?
(二)三级缓存的作用
- 一级缓存的作用:用于存放完整的bean对象;
- 二级缓存的作用:用于判断两对象之间的依赖是不是循环依赖;
- 三级缓存的作用:用于解决AOP代理的问题,存放函数接口。
- 对二级缓存下的所有代码加锁:避免多线程情况下获取到不完整的bean对象。
- 创建bean前对二三级缓存加锁并再次从一级缓存中获取bean:防止下面这种情况:多线程下,一个线程刚判断完一二三级缓存中没有bean,此刻另一个线程刚好创建了一个完整bean。
- Spring中没有解决构造函数的循环依赖,多例存在循环依赖则直接抛出异常。
参考:循环依赖| ProcessOn免费在线作图,在线流程图,在线思维导图