spring循环依赖和三级缓存

deity-night / 2023-05-19 / 原文

是什么

一个或者多个bean之间存在直接或者间接的依赖关系并构成循环调用

根本原因还是在代码的一个设计上,因为模块耦合度较高的情况下,依赖的复杂度一定会增加

表现形态

互相依赖:A-B   B-A

 间接依赖

 自我依赖

 解决

三级缓存来解决部分循环依赖的问题

三级缓存

其实就是用来存放不同类型的bean

  • 第一级缓存存放的是完全初始化号的bean,这个bean可以直接被使用
  • 第二级缓存存放的是原始的bean对象,也就是说bean里面的属性还没有北赋值或者依赖注入
  • 第三极缓存存放的是一个bean工厂对象,用来生成原始bean对象并且放入到二级缓存中

假设Bean A 和 Bean B之间存在循环依赖

 核心思想是把bean的实例化和bean中的属性注入过程分离

采用一级缓存来存放完整的bean实例

采用二级缓存来存储不完整的Bean实例,通过不完整的bean实例作为突破口来解决循环依赖的问题

至于第三季缓存主要是解决代理对对象的循环依赖问题

注:只能解决单实例存在的循环引用问题

且,以下四种情况需要人为干预

1.多实例的Setter注入导致的循环依赖,需要把Bean改成单例。

2.构造器注入导致的循环依赖,可以通过@Lazy注解

3.@Dependson导致的循环依赖,找到注解循环依赖的地方,迫使它不循环依赖。·

4.单例的代理对象Setter注入导致的循环依赖

  • 可以使用@Lazy注解
  • 或者使用@DependsOn注解指定加载先后关系