Spring构造器注入产生的循环依赖以及解决办法
一、循环依赖描述
问题描述:Bean A依赖B,Bean B依赖A,这种情况下即为循环依赖,如下:
Bean A --> Bean B --> Bean A
导致问题:当存在循环依赖时,Spring将无法决定先创建哪个bean,这种情况下,Spring将产生异常BeanCurrentlyInCreationException。
二、构造器循环依赖复现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @Component @Slf4j public class E1 { private E2 e2; public E1(E2 e2) { log.info( "E2({})" , e2); this .e2 = e2; } } @Component @Slf4j public class E2 { private E1 e1; public E2(E1 e1) { log.info( "E1({})" , e1); this .e1 = e1; } } |
启动项目报错:
1 2 3 4 5 6 7 8 9 10 11 12 13 | *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: ┌─────┐ | e1 defined in file [F:\StudyProject\example-springboot-demo\springboot-demo\target\classes\com\zhixi\config\E1. class ] ↑ ↓ | e2 defined in file [F:\StudyProject\example-springboot-demo\springboot-demo\target\classes\com\zhixi\config\E2. class ] └─────┘ |
三、如何解决构造器循环依赖
1、@Lazy注解
对E2进行延迟加载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Component @Slf4j public class E1 { private E2 e2; public E1(@Lazy E2 e2) { this .e2 = e2; } } @Component @Slf4j public class E2 { private E1 e1; public E2(E1 e1) { this .e1 = e1; } } |
2、使用对象工厂:ObjectFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Component @Slf4j public class E1 { private ObjectFactory<E2> e2; public E1(ObjectFactory<E2> e2) { this .e2 = e2; } } @Component @Slf4j public class E2 { private E1 e1; public E2(E1 e1) { this .e1 = e1; } } |
3、使用Provider接口:实质也是一个对象工厂
需要在pom.xml中添加pom:
1 2 3 4 5 | <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> |
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import org.springframework.stereotype.Component; import javax.inject.Provider; @Component public class E1 { private Provider<E2> e2; public E1(Provider<E2> e2) { this .e2 = e2; } } @Component public class E2 { private E1 e1; public E2(E1 e1) { this .e1 = e1; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
2022-08-11 读取resources下的资源