spring循环依赖为什么是三级缓存
-
Spring循环依赖是指在Bean的创建过程中,存在互相依赖的情况。当两个或多个Bean互相依赖时,如果没有合适的解决办法,就会导致循环依赖的问题。
为了解决循环依赖的问题,Spring使用了三级缓存机制。这个三级缓存分别是singletonFactories、earlySingletonObjects和singletonObjects。
首先,当一个Bean正在创建过程中,Spring会把正在创建的Bean放到singletonFactories缓存中。每个Bean的创建都有一个缓存,存放着正在创建的Bean的ObjectFactory。当下一个正在创建的Bean需要使用到前一个正在创建的Bean时,Spring会从singletonFactories缓存中获取前一个Bean的ObjectFactory,从而解决循环依赖的问题。
其次,当一个Bean创建完成后,Spring会将其放到earlySingletonObjects缓存中。这个缓存主要用于解决循环依赖中的“原型Bean作为构造函数参数”的问题。当一个Bean需要使用到一个正在创建中的原型Bean时,Spring会从earlySingletonObjects缓存中获取已创建完成的Bean。
最后,当所有的Bean创建完成后,Spring会将这些Bean放到singletonObjects缓存中。这个缓存是最终的Bean对象缓存,当一个Bean需要被其他Bean引用时,Spring会从singletonObjects缓存中获取Bean对象。
总结来说,Spring将循环依赖的解决方案分为了三个阶段:创建中的Bean放到singletonFactories缓存中,已创建完成的Bean放到earlySingletonObjects缓存中,最终的Bean对象放到singletonObjects缓存中。这种三级缓存的机制可以有效地解决循环依赖的问题,确保Bean的正确创建和使用。
1年前 -
Spring循环依赖的三级缓存是为了解决循环依赖的问题。当Bean A依赖Bean B,而Bean B又依赖Bean A时,就会出现循环依赖的情况。
在Spring中,通过使用三级缓存来解决循环依赖的问题。三级缓存的原理如下:
-
第一级缓存:提前暴露的单例对象。当一个Bean正在创建时,它的创建实例操作将会被存储在一个以Bean名称为键的早期对象工厂缓存中。这个缓存中存储的是对象的创建开始时间戳信息。
-
第二级缓存:早期暴露的单例对象。当一个Bean创建实例操作正在进行中时,它可以从第一级缓存中获取依赖Bean实例。通过将依赖Bean实例存储在一个以Bean名称为键的早期对象工厂缓存中,这个缓存中存储的是依赖Bean实例的代理对象。
-
第三级缓存:已经完全创建的单例对象。当一个Bean创建实例操作完成后,它可以从第二级缓存中获取依赖Bean实例。通过将依赖Bean实例存储在一个以Bean名称为键的缓存中,这个缓存中存储的是依赖Bean实例的完全创建的对象。
使用三级缓存的步骤如下:
-
创建bean的实例,但是并未将其放入缓存中。
-
将实例放入第一级缓存中。
-
检查第二级缓存中是否存在该bean的代理对象,如果存在,则直接返回。
-
将实例放入第二级缓存中。
-
使用依赖注入的方式将bean的依赖注入。
-
创建并初始化bean的实例。
-
将实例放入第三级缓存中。
-
返回第三级缓存中的完全创建的对象。
通过以上步骤,Spring能够解决循环依赖的问题,并且保证每个依赖的Bean都能正确初始化和创建。这样,循环依赖的问题就得到了解决。
1年前 -
-
在Spring容器中,当两个或多个Bean相互依赖时,就会出现循环依赖的情况。循环依赖是指两个或多个Bean之间相互依赖,形成一个环状的依赖关系。在Spring容器中解决循环依赖的过程中,使用了三级缓存来管理对象的创建过程。
为了更好地理解为什么Spring循环依赖要使用三级缓存,我们先了解一下Spring Bean的创建过程。
- 第一级缓存(singletonObjects):在创建Bean时,首先会检查一级缓存中是否存在该Bean的实例,如果存在,则直接返回该实例,否则继续下一步操作。
- 第二级缓存(earlySingletonObjects):在创建Bean的过程中,Spring会将正在创建的Bean保存到第二级缓存中。这样,当循环依赖时,可以通过第二级缓存中的Bean来解决循环依赖的问题。
- 第三级缓存(singletonFactories):如果第二级缓存中没有找到对应的Bean实例,那么Spring就会通过Bean的工厂方法创建一个新的Bean实例,并保存在第三级缓存中。同时,Spring也会将该Bean的工厂方法保存到第三级缓存中,以便后续使用。
- 创建Bean实例:在创建Bean实例的过程中,如果发现循环依赖的情况,Spring会从第三级缓存中获取对应的Bean工厂方法,并执行工厂方法创建Bean实例。创建完毕后,将该实例保存在第二级缓存中,并在创建过程中完成依赖注入。
因此,为了解决循环依赖的问题,Spring使用了三级缓存来管理Bean的创建过程。当出现循环依赖时,Spring会通过三级缓存中的Bean工厂方法来创建Bean实例,以解决循环依赖的问题。通过使用三级缓存,Spring确保了Bean在被创建的同时能够解决循环依赖问题,保证了Bean的正确初始化。同时,三级缓存的使用也避免了无限递归的问题,以提高性能和效率。
总结来说,Spring循环依赖为了解决相互依赖的对象创建问题使用了三级缓存的机制,通过使用三级缓存,Spring确保了Bean在被创建的同时能够解决循环依赖问题。
1年前