什么是循环依赖
循环依赖就是循环引用,在spring中,就是两个或者多个bean相互之间持有对方。如下图,ClassA引用ClassB,ClassB引用ClassC,ClassC又引用ClassA,最终它们形成了一个环,这就是循环依赖。
Spring中的循环依赖
spring中将循环依赖分成了3中情况,分别是:
- 构造器循环依赖
- prototype范围的依赖处理
- setter循环依赖
构造器循环依赖
通过构造器注入构成的循环依赖,此依赖无法解决
。在Spring中会抛出BeanCurrentlyInCreationException异常表示循环依赖。
对于构造器注入构成的循环依赖,在创建ClassA的时候,构造器需要ClassB,然后去创建ClassB,在创建ClassB的时候发现需要ClassA,形成了一个死循环,无法完成创建。
prototype范围的依赖处理
对于prototype
作用域的bean,spring容器无法完成依赖注入,因为spring不像缓存单例那样缓存prototype作用域的bean。
setter循环依赖
表示通过setter注入方式构成的循环依赖,spring通过提前暴露构造器注入但未完成其他步骤(如setter操作)的bean来完成setter注入造成的循环依赖。
自己简单的用代码来展示spring解决单例setter循环依赖的方式,具体spring中如何解决感兴趣可以自己阅读源码。
创建两个循环依赖的类,ClassA和ClassB。
1 | package io.github.brightloong.lab.spring.cyclicdependence; |
###
1 | package io.github.brightloong.lab.spring.cyclicdependence; |
ObjectFactory用来模仿Spring解决循环依赖获取bean
1 | package io.github.brightloong.lab.spring.cyclicdependence; |
客户端调用
1 | package io.github.brightloong.lab.spring.cyclicdependence; |
输出如下:
1 | I am ClassB. Who are you? |
从输出可以发现:
- ClassA和ClassB都成功实例化
- 都是单例