行业资讯 2025年08月6日
0 收藏 0 点赞 703 浏览 1541 个字
摘要 :

文章目录 一、什么是循环依赖 二、怎么判断产生了循环依赖 三、3种循环依赖的情况 四、Spring循环依赖如何解决 方法一: 方法二: 五、总结 在使用Spring开发java项……




  • 一、什么循环依赖
  • 二、怎么判断产生了循环依赖
  • 三、3种循环依赖的情况
  • 四、Spring循环依赖如何解决
    • 方法一:
    • 方法二:
  • 五、总结

在使用Spring开发java项目的过程中,经常是使用注解注入,在很多时候不知不觉中就会形成循环依赖,而且一般情况下还是很难发现的,循环依赖会对项目产生一定的不良影响,因此我们需要明白Spring的循环依赖是什么?怎么判断是否产生循环依赖的以及它的解决方式有哪些?

一、什么是循环依赖

首先明白一点,循环依赖并不是说简单的两个类相互依赖对方,比如我们常常在使用mybatis框架时,为了实现一对一的关系,常常在实体类中会相互定义对方,方便由一方查询另一方的信息,在java开发中类的相互依赖是很正常的,比如如下:

// User 依赖了idCard
class User{
    public IdCard idCard;
}
// IdCard 依赖了User 
class IdCard  {
    public User user;
}

然而循环依赖一般是指多个bean之间相互依赖,形成了一个闭环。 比如:A依赖于B、B依赖于C、C依赖于A。

通常来说,如果问spring容器内部如何解决循环依赖, 一定是指默认的单例Bean中,属性互相引用的场景。也就是说,Spring的循环依赖,是Spring容器注入时候出现的问题。
Spring循环依赖是什么及其解决方式
比如类似如下代码就会产生循环依赖:

// 第一部分
@Component
public class A {
    @Autowired
    private B b;
}
// 第二部分
@Component
public class B {
    @Autowired
    private C c;
}
// 第三部分
@Component
public class C {
    @Autowired
    private A a;
}

二、怎么判断产生了循环依赖

判断产生循环依赖,一般很难通过人工审查代码发现,因为每个类可能会引用很多其他类,又比较分散,一般都是在项目联调测试或者发布启动的时候会在日志中打印出来才被发现,也可能在本地运行没问题,在服务器打包就出错,可能这次打包没错,下次打包就有错了,只要有一次出错类似如下图,就说明存在该问题。
Spring循环依赖是什么及其解决方式
但也有个比较好的方法就是,当Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。

三、3种循环依赖的情况

①构造器的循环依赖:这种依赖spring是处理不了的,直接抛出BeanCurrentlylnCreationException异常。
②单例模式下的setter循环依赖:通过“三级缓存”处理循环依赖,能处理。
③非单例循环依赖:无法处理。原型(Prototype)的场景是不支持循环依赖的,通常会走到AbstractBeanFactory类中下面的判断,抛出异常。

四、Spring循环依赖如何解决

方法一:

  • 不使用基于构造函数的依赖注入
  • 在字段上使用@Autowired注解,让Spring决定在合适的时机注入。【推荐】
  • 用基于setter方法的依赖注射取代基于构造函数的依赖注入来解决循环依赖。
  • @Autowired注解上方加上@Lazy注解(延迟加载)

方法二:

使用SpringContextHolder获取已经存在的bean

在进行解决Spring循环依赖问题时最好先去了解下Spring内部是如何解决循环依赖问题的,这也是面试中经常会被问到的问题,具体的可以去看这篇文章,深入了解下解决循环依赖的底层逻辑。

Spring如何解决循环依赖问题(面试题)

文章目录 一、针对面试题 二、什么是循环依赖 三、循环依赖的类型 四、Spring中循环依赖的几种场景及Spr […]

五、总结

当然,这里的方案只能针对部分循环依赖的情况,更具体的解决方案还是要了解Spring产生循环依赖的底层逻辑,这样才能更好地对症下药,彻底解决。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/8260.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号