Spring其实可以分为三个场景会有循环依赖的可能:构造器之间的循环依赖、字段注入的循环依赖(DI)、setter方法注入的循环依赖(DI),下面分别从三个地方说下这些循环依赖。
构造器循环依赖
构造器的循环依赖其实在Spring中其实还是无解的,因为无论如何在进行对象构建时都是需要调用构造器的,即使Spring是采用反射技术来创建java对象,反射还是需要依赖构造器来进行对象的创建,所以单纯的构造器形成的循环依赖在Spring中也是无解的
字段注入循环依赖
字段注入也是我们日常开发中最长使用的一种DI的方式了,这种循环依赖Spring已经替我们解决了,所以使用起来不会报错,先来说说字段注入的原理这样会更方便我们理解Spirng中是如何形成循环依赖的。当我们在一个类G中DI了H的对象,那么当Spring容器在进行IOC时通过java的反射技术便会尝试将H的对象进行传递给G,实例化H时则会尝试初始化G这样就会形成死循环。这里的循环依赖于java原生的依赖并不相同,因为对象的创建时并没有相互依赖,产生依赖的地方其实是在DI的阶段,不过此时Spring依然是利用反射技术来进行DI,所以就会有这样一个问题:Spring利用反射创建了G对象但是属性实例化失败了,同样的H也是。不过我们在日常开发中好像发现并没有类似问题产生,其实Spring已经帮我们解决了这一问题
setter方法注入循环依赖
最后要说的这一种循环依赖就是使用setter方法进行属性注入,这种循环依赖依然不会有问题,产生的原理其实和上面的实例变量方式进行属性注入是没有区别的。但是对于这个问题的解决和第一种是有区别的,因为Spring在进行setter方法注入时,是在Bean实例化时进行的,而即使在实例化期间,也有循环依赖易软不会有循环依赖问题