本质上告诉你springbean注入为什么有些不能有循环依赖

本质上告诉你springbean注入为什么有些不能有循环依赖

网上有很多博主,要么就是表面的解释下死循环的不可行,要么就是搬出源代码分析为什么会抛出BeanInCreationException,
都没有从本质上解释spring为什么不能有循环依赖,循环依赖难道真的就因为感觉造成“死循环”,就认为任何地方不可以“循环依赖”了吗?
于是带着问题,不断翻阅资料,但是总是找不出为什么不能有循环依赖的解释,这才有了本质上的解决了心中的why冲动!以下就是我从本质上思考的一些心得把。

下面我用构造函数和属性注入两种方式,分别解释为什么循环依赖跟bean的模式,有些有关,有些又无关呢?

  1. .构造函数注入

    构造函数注入bean,不管单例还是原型,会构成循环依赖是因为:


             
   
   
             
    

通过构造函数创建A时,大家都知道,必须先创建B,这时候创建一个B至少需要创建一个A,但注意,此时其实一个A都还没有创建呢,所以前面的B也创建不了啊,所以A,B就一直创建不了,如果更大的闭环,其实也是一个都创建不了了。
这里非常要注意,“至少一个”,这几个字眼,这是结合分析单例和原型模式了,还有就是它的原因是,因为一个都创建不了了,而不是什么“死循环”的原因了。

2.属性注入

2.1 再说下setter注入,其中一个是原型模式,也不能有循环依赖的


         
         
        
         
        

如果是属性注入,先会创建完A,需要依赖B,然后再创建完B,发现又需要A,又需要创建好一个A,由于是prototype模式,是可以创建多个A,B的,结果又会创建B,如此循环,根本就不会结束了,这才是真的死循环的原因。
这里要注意字眼,“创建完”,这里的意思就是已经创建好了,而不是将要创建,网上很多没有把这种先后顺序说清楚,导致不能理解构造注入和属性注入的区别。

如果是全是单例模式,为什么就不会了呢,因为,创建B不会再需要创建A了,直接取原来创建的A依赖进去就可以了,也就不会再创建A,继而创建B,一直下去,造成死循环了,所以,其实就是相比prototype模式,不会造成死循环。
至此就把spring框架为什么一定要解决这几种循环依赖的原因彻底说清楚了。一种构造函数实例化对象的机制造成的,一种是要达成prototype模式的设计目的造成的!
所以,这些都是在spring框架设计之初,就已经想好的。而不仅是spring组织是用代码来这样定义告诉我们就要这么用。而是spring组织也必须,遵循这样的java机制和设计,才能完善一个技术的实现规范,也就是实现这样一门科技,事先就需要想好它一些不能存在的场景,从而从设计和代码逻辑上面一开始就避免掉。

你可能感兴趣的:(剖析本质)