Spring如何解决循环依赖

83 阅读3分钟

从哪些方面下手?

第一个你要跟它扯到关于Spring当中的bean它究竟它的一个整体的大概的实例化过程是怎么来的,说白了,你要跟它扯到关于Spring当中的BeanDefintion这个概念。就是我们一个bean使用BeanDefintion来产生过来的。

第二呢,就是你要讲这个Spring的循环依赖的话,你肯定绕不过这个Bean的生命周期,如果Spring bean它没有这个生命周期的话,那这个循环根本就没有什么可问的。

第三个,Spring当中的这个循环依赖里的这个有三个环节,有三个Map来解决这个循环依赖的。

待完善~

循环依赖是指两个或更多的bean对象之间相互依赖,其中至少有一个bean对象直接或者间接地依赖于另一个bean对象,而另一个bean对象也直接或者间接地依赖于该bean对象。如何处理循环依赖是一个非常重要的问题,因为如果不能解决循环依赖问题,就会导致应用程序无法启动或者启动后出现异常。 Spring提供了两种主要的解决循环依赖的方法:

  1. 通过构造函数注入解决循环依赖

在使用构造函数注入时,Spring在初始化bean时会根据构造函数的参数来决定注入哪些bean。如果有循环依赖的情况,Spring会在容器创建bean的过程中抛出BeanCurrentlyInCreationException异常。为了解决这个问题,可以使用工厂模式,通过一个工厂类来创建所有的bean对象,并且让Spring管理这个工厂类。这样,工厂类就可以处理循环依赖问题,保证bean对象的正确创建。

  1. 通过setter方法注入解决循环依赖

在使用setter方法注入时,Spring在初始化bean时会先创建一个空bean对象,并且为其注入属性。如果属性也有循环依赖,Spring会使用默认的无参构造函数创建一个空对象,并将其添加到对象池中,等待后续赋值。一旦对象池中存在待注入属性的对象,Spring就会将其注入到当前bean对象中,并且在注册销毁回调函数时保持当前bean对象的状态。这样,在处理完其他bean对象之后,Spring就会遍历所有空对象,将其注入到对应的属性中。如果找不到对应的属性,则会抛出异常。 总的来说,Spring可以通过构造函数注入和setter方法注入的方式解决循环依赖的问题。在实际应用中,应该选择合适的方式来处理循环依赖,保证应用能够正常启动并且保证安全性和可维护性。

三级缓存属于Spring框架中的对象创建及依赖注入的缓存体系,用于解决循环依赖的问题。

具体而言,Spring在创建对象时,会将创建好的对象存入三级缓存中。三级缓存包括:

singletonObjects:单例对象池,池中存放着已经完全创建好的单例对象。 earlySingletonObjects:提前曝光的单例对象池,存放着一部分未完成初始化的单例对象,这些对象在创建时会提前曝光,以便解决循环依赖问题。 singletonFactories:工厂对象池,存放着一些用于创建单例对象的工厂对象。

通过三级缓存的使用,Spring可以保证在创建循环依赖的对象时,能够正确地完成依赖注入,避免出现BeanCurrentlyInCreationException异常等问题。当创建完对象之后,Spring会将对象从三级缓存中移除,以避免造成内存泄漏等问题。 总之,三级缓存在Spring框架中扮演着非常重要的角色,是解决循环依赖的关键机制之一。