2020年7月15日
Spring的循环依赖和处理
先说结论:构造器和原型循环依赖,无法处理 ,setter注入和单例@Autowired注入可以处理。
原因:解决循环依赖,使用的是bean的中间态,需要在实例化(构造器执行之后)才能拿到这个中间对象。

创建一个bean,doCreateBean方法,分为createBeanInstance,populateBean和 initalizeBrann,单例和属性注入的循环依赖出现在populateBean,是可以处理的。
三级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //一级缓存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存
//正在创建的bean,创建完成时会将其移出
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
先从一级缓存singletonObjects中去获取。(如果获取到就直接return)
如果获取不到或者对象正在创建中(isSingletonCurrentlyInCreation()),那就再从二级缓存earlySingletonObjects中获取。(如果获取到就直接return)
如果还是获取不到,且允许singletonFactories(allowEarlyReference=true)通过getObject()获取。就从三级缓存singletonFactory.getObject()获取。(如果获取到了就从singletonFactories中移除,并且放进earlySingletonObjects。其实也就是从三级缓存移动(是剪切、不是复制哦~)到了二级缓存)
加入singletonFactories
三级缓存的前提是执行了构造器就是在createBeanInstance方法之后执行,所以构造器的循环依赖没法解决
如果三级缓存获取不到,那就创建,然后进入singletonFactories,进入earlySingletonObjects,进入singletonObjects,得到bean。
参考: https://www.cnblogs.com/longy2012/articles/12834762.html