项目中遇到的循环依赖问题

一、首先我们要了解 什么是循环依赖:

1. 什么是循环依赖?

所谓的循环依赖是指,A 依赖 B,B 又依赖 A,它们之间形成了循环依赖。

它们之间的依赖关系如下:

 

 报错显示:

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   jwPgPzServiceImpl defined in file [D:\新建文件夹\ELXY\smart_campus\jwpx\target\classes\com\sinosoft\springbootplus\assess\application\service\impl\JwPgPzServiceImpl.class]
      ↓
   pgMbBaseinfoServiceImpl defined in file [D:\新建文件夹\ELXY\smart_campus\pgwj\target\classes\com\sinosoft\springbootplus\evaluate\application\service\impl\PgMbBaseinfoServiceImpl.class]
┌─────┐
|  jwXyStudentServiceImpl defined in file [D:\新建文件夹\ELXY\smart_campus\jwpx\target\classes\com\sinosoft\springbootplus\student\application\service\impl\JwXyStudentServiceImpl.class]
↑     ↓
|  hqKfStudentServiceImpl defined in file [D:\新建文件夹\ELXY\smart_campus\hqfw\target\classes\com\sinosoft\springbootplus\dorm\application\service\impl\HqKfStudentServiceImpl.class]
└─────┘

 看到错可得知jwXyStudentServiceImpl和hqKfStudentServiceImpl 造成的循环依赖问题.

二、三种循环依赖

在Spring中一共有三种循环依赖,构造器循环依赖,Setter循环依赖,和Prototype作用域的循环依赖,对于这三种循环依赖,Spring并不是都解决的.

通过表格来了解下:

名称是否可解决循环依赖
构造器循环依赖
Setter循环依赖
Prototype作用域的循环依赖

三、解决构造函数相互注入造成的循环依赖:

前面说Spring可以自动解决单例模式下通过setter()方法进行依赖注入产生的循环依赖问题。而对于通过构造方法进行依赖注入时产生的循环依赖问题没办法自动解决,那针对这种情况,我们可以使用@Lazy注解来解决。

也就是说,对于类A和类B都是通过构造器注入的情况,可以在A或者B的构造函数的形参上加个@Lazy注解实现延迟加载。@Lazy实现原理是,当实例化对象时,如果发现参数或者属性有@Lazy注解修饰,那么就不直接创建所依赖的对象了,而是使用动态代理创建一个代理类。

比如,类A的创建:A a=new A(B),需要依赖对象B,发现构造函数的形参上有@Lazy注解,那么就不直接创建B了,而是使用动态代理创建了一个代理类B1,此时A跟B就不是相互依赖了,变成了A依赖一个代理类B1,B依赖A。但因为在注入依赖时,类A并没有完全的初始化完,实际上注入的是一个代理对象,只有当他首次被使用的时候才会被完全的初始化。

当写上@Lazy注解就不会出现循环以来的问题了,完美解决.

    @Lazy
    @Autowired
    private HqKfStudentApiService hqKfStudentApiService;

    @Lazy
    @Autowired
    private StudentDorm studentDorm;

网上找到的循环依赖问题全景图,大家可以看一下:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值