Spring中的循环依赖出现示例

循环依赖的场景:

service中的类A和类B,类A中需要DI类B,而类B中又需要DI类A。但环并不一定会出现,跟DI的方式有关。

Spring中的循环依赖有:

  • 构造器循环依赖(会出现环的情况,项目无法启动)
  • Filed属性注入依赖(类AB的Scope不同时,有不同的情况。)

代码用例:

构造器循环依赖: 将陷入环,项目启动失败。

@Service
public class LoopA {
    LoopB loopB;

    public LoopA(LoopB loopB) {
        this.loopB = loopB;
    }

    public String sout() {
        return loopB.sout();
    }
}



-----------------------------------

@Service
public class LoopB {
    LoopA loopA;

    public LoopB(LoopA loopA) {
        this.loopA = loopA;
    }

    public String sout() {
        return "this is class loop b";
    }
}

 先构造器(LoopA )的循环注入:: 将陷入环,项目启动失败。

@Service
public class LoopA {

    public LoopA(LoopB loopB) {
    }

}

----------------------------


@Service
public class LoopB {
    @Autowired
    LoopA loopA;

    public LoopB() {
    }

}

Filed都为多例的类的注入:将陷入环,项目启动失败。

@Service
@Scope("prototype")
public class LoopA {
    @Autowired
    LoopB loopB;

    public String sout() {
        return loopB.sout();
    }
}

-----------------------------------------------------

@Service
@Scope("prototype")
public class LoopB {
    @Autowired
    LoopA loopA;

    public String sout() {
        return "this is class loop b";
    }
}

 在多例类(先初始化)中注入单例类(后初始化):将陷入环

//先被controller调用该类
@Service
@Scope("prototype")
public class LoopA {
    @Autowired
    LoopB loopB;

    public String sout() {
        return loopB.sout();
    }
}


----------------------------------


@Service
public class LoopB {
    @Autowired
    LoopA loopA;

    public String sout() {
        return "this is class loop b";
    }
}

环的陷入,是因为创建LoopA类需要LoopB类,LoopB类又需要LoopA类,在获取LoopA类时,发现LoopA类被存在一个未创建完成的HashSet中,于是抛出陷入循环的异常。

Filed都为单例的类的注入:不会陷入环,会使用到spring单例的三级缓存。

@Service
public class LoopA {
    @Autowired
    LoopB loopB;
    
    public String sout() {
        return loopB.sout();
    }
}


------------------------------------

@Service
public class LoopB {
    @Autowired
    LoopA loopA;

    public String sout() {
        return "this is class loop b";
    }
}

在单例类(先初始化)中注入多例类(后初始化):不会陷入环

@Service
public class LoopA {
    @Autowired
    LoopB loopB;

    public LoopA() {
    }

    public String sout() {
        return loopB.sout();
    }
}

--------------------------------------------------、

@Service
@Scope("prototype")
public class LoopB {
    @Autowired
    LoopA loopA;

    public LoopB() {
    }

    public String sout() {
        return "this is class loop b";
    }
}

从日志中也可以看到,当对单例类(LoopA类)进行初始化时,还未执行构造函数,类就已经被实例化出来了,并存放于第三级缓存 singletonFactories 的HashMap中,再注入单例类(LoopA类)中的属性,当其他的类(单例或多例)在循环注入单例类(LoopA类)时,就可以获取到单例类(LoopA类),此时便跳出了循环

 

有兴趣的同学可以看看另外一篇博客, Spring 循环依赖的源码解毒与灵魂拷问:https://blog.csdn.net/BigBug_500/article/details/109050337

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值