spring框架如何解决循环依赖

一、什么是循环依赖

spring框架如何解决循环依赖,我们就得先知道什么是循环依赖

根据这个名字,大家可以看出来,就是循环和依赖,其实和我们调用方法中的死循环很像,它发生在spring上下文加载所有的Bean时,一个类A依赖于另一个类B,而类B又依赖于类A:

Bean A →Bean B→Bean A.....

演示如下:

有两个相互依赖的类A,B

 

配置类,指定要扫描的包:

最后就是测试,junit来测试

如果运行,并且两个类之间相互依赖,则会报错,如下:

二、如何解决循环依赖

1.最有效、最直接的办法就是重新设计,将组件的结构设计的更明确,避免循环依赖

2.使用set注入:

只有构造方法是在上下文加载时就要求被注入,容易出现循环依赖,所以我们可以使用其他注入方式进行依赖注入,set注入与构造注入不同,set注入是在被需要的时候才会注入。

3.使用@Lazy

对循环依赖的两个类使用@Lazy,通过延迟加载的方式防止循环依赖,也就是它没有完全的初始化,而是创建一个代理将它注入另一个,只有第一次使用它时才会创建

先举三个解决循环依赖的例子,有兴趣的朋友可以了解一下其他的解决循环依赖的方法,找到了评论区发给我(˵¯͒〰¯͒˵)

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring框架解决循环依赖的方法是通过使用“提前暴露”的方式来解决。当存在两个或多个bean相互依赖时,Spring会首先实例化所有没有依赖关系的bean,然后将正在创建的bean的ObjectFactory暴露给Spring容器。当Spring容器遇到循环依赖时,它会使用ObjectFactory来解决循环依赖,即在创建Bean时,首先创建一个未完成的Bean实例,然后使用ObjectFactory将未完成的Bean实例注入到相应的依赖中,最后完成Bean的创建和注入。这样可以解决循环依赖的问题,并且保证依赖注入的正确性。 ### 回答2: Spring解决循环依赖的问题通过三级缓存来实现。 首先,当BeanA需要BeanB作为依赖注入时,Spring会先检查BeanB是否已经创建,如果未创建,则创建一个代理对象并将其提前暴露,标记为正在创建。然后Spring继续创建BeanA,并将其注入到BeanB的属性中。此时Spring会将BeanA放入一级缓存中。 接下来,当Spring创建BeanB时,发现BeanB依赖BeanA,此时Spring会查看一级缓存中是否存在BeanA,如果存在,则直接返回已经创建好的BeanA。如果一级缓存中不存在BeanA,则继续创建BeanA,并将其注入到BeanB的属性中。然后Spring将BeanB放入二级缓存中。 最后,当创建BeanA完成后,Spring会检查二级缓存中是否存在BeanB,如果存在,则将BeanB更新为已创建状态,同时将其放入三级缓存中。接着Spring会将BeanA中的属性注入到BeanB中,完成整个循环依赖解决。 需要注意的是,如果循环依赖的Bean中存在有其他的依赖关系,那么Spring会通过构造器注入来解决。 通过三级缓存的方式,Spring能够解决循环依赖的问题,并保证依赖注入的顺序正确,避免了循环依赖带来的死循环问题。 ### 回答3: Spring通过三级缓存解决循环依赖的问题。 当Bean A和Bean B互相依赖时,Spring将A的创建过程包装在一个提前暴露接口的addSingletonFactory()方法中,将B的创建过程包装在一个获取B的实例的ObjectFactory中。然后,Spring会先创建A的实例,但还没有完成依赖注入,此时将A的ObjectFactory放入当前单例Bean的三级缓存。 接下来,Spring会开始创建B的实例,当B的依赖注入时,Spring会发现B依赖于A,此时会从三级缓存中取出A的ObjectFactory,并创建A的实例,并完成A的依赖注入。 最后,Spring将A的实例放入二级缓存,并从三级缓存移除。接着,Spring会将B的实例放入一级缓存,并完成B的依赖注入。 通过这种方式,Spring能够解决循环依赖的问题,保证了所有依赖关系的正确注入。同时,Spring在三级缓存的处理过程中,使用了线程安全的ConcurrentHashMap,确保了多线程环境下的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值