spring循环依赖和原型模式的关系

网上的说法是:构造器注入方式出现循环依赖时会在启动的时候抛出异常,而属性注入的方式出现循环依赖时会在调用的时候抛出异常,但是给出的代码执行起来跟理论结果不一致,直到某天看到一篇文章提到跟单例和原型有关。

@Component
public class ClassA {

    @Autowired
    private ClassBclassb;

    private Stringname ="classA的名字";
    public StringgetName() { return name;}
}

@Component
public class ClassB {
    @Autowired
    private ClassAclassa;
    private Stringname ="classB的名字";
    public StringgetName() {return name;}
}
@Autowired
private ClassA classA;

@Test
public void testRelay(){
System.out.println(classA.getName());
    System.out.println("=================over");
}

这种方式,理论上打印时会报错,但是实际上会执行成功,并且 classA有值
如果在ClassA和ClassB上加上

@Scope(value = "prototype")

那么启动就会报错,发生了循环依赖,但是只在ClassA或者ClassB上加以上注解不会出现问题
结论:
\color{red}{就实验结果得出的初级结论,如有大神,请不吝赐教}
  属性注入确实可能产生循环依赖,但是本质是单例多例的问题,当创建ClassA后,对属性注入值时,发现需要ClassB,所以去构建ClassB,由于ClassB又依赖ClassA。
  假如是单例模式,那么此时ClassA已经有了(即使没有赋值,但是bean已经存在了),所以ClassB的ClassA字段直接赋值然后返回,ClassA初始化完成,由于对象是地址值引用,所以ClassB的ClassA字段也更新成了最新的ClassA的bean(同一地址)。
  但是如果都是多例模式且,ClassB需要ClassA,但是ClassA又是多例模式,则ClassB又去创建ClassA,然后ClassA又去创建ClassB,循环出现。
  如果只有一个是多例,一个单例(spring默认是单例模式),假如是ClassA单例,ClassB多例,ClassA注入ClassB时创建ClassB,ClassB注入ClassA时,ClassA有了,直接注入,然后返回,不会出现循环依赖。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容