下面说Spring的三级缓存
// 从上至下 分表代表这“三级缓存” private final MapsingletonObjects = new ConcurrentHashMap<>(256); //一级缓存 private final Map earlySingletonObjects = new HashMap<>(16); // 二级缓存 private final Map > singletonFactories = new HashMap<>(16); // 三级缓存 ... // 这个缓存也十分重要:它表示bean创建过程中都会在里面呆着,它在Bean开始创建时放值,创建完成时会将其移出 private final Set singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); // 当这个Bean被创建完成后,会标记为这个 注意:这里是set集合 不会重复。至少被创建了一次的 都会放进这里 private final Set alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
实现循环依赖的原理
一、如果没有2级缓存,只有一级和三级的情况下,可以吗?Spring的循环依赖的理论依据基于Java的引用传递,获得对象的引用时,对象的属性是可以延后设置的。
不可以,首先要明白,一次缓存的是完全实例化好的Bean,二级缓存是半成品,三级缓存是ObjectFactory
如果去掉了二级缓存,假设A依赖B,B依赖A,当实例化B的时候,发现三级缓存有A的ObjectFactory对象,然后拿到A的实例对象,拿完只有必须要保证其他依赖的Bean是一个实例,多次调用产生的对象肯定是不一样的(前提是A是AOP代理的Bean),所以一定要把A从三级转移出来,如果只有一级缓存,那么放里面肯定是不合适的。所以不能少二级缓存。
可以的,但是站在性能上不合适,就是发现是AOP代理对象,直接生成然后再去实例化,不使用懒加载的方式去处理。



