前言

        说起Spring中循环依赖的解决办法,相信很多园友们都或多或少的知道一些,但当真的要详细说明的时候,可能又没法一下将它讲清楚。本文就试着尽自己所能,对此做出一个较详细的解读。另,需注意一点,下文中会出现类的实例化跟类的初始化两个短语,为怕园友迷惑,事先声明一下,本文的实例化是指刚执行完构造器将一个对象new出来,但还未填充属性值的状态,而初始化是指完成了属性的依赖注入。

一、先说说Spring解决的循环依赖是什么

        Java中的循环依赖分两种,一种是构造器的循环依赖,另一种是属性的循环依赖。

        构造器的循环依赖就是在构造器中有属性循环依赖,如下所示的两个类就属于构造器循环依赖:

复制代码
 1 @Service  2 public class Student {  3     @Autowired  4     private Teacher teacher;  5  6     public Student (Teacher teacher) {  7         System.out.println("Student init1:" + teacher);  8     }  9 10     public void learn () { 11         System.out.println("Student learn"); 12     } 13 }
复制代码
复制代码
 1 @Service  2 public class Teacher {  3     @Autowired  4     private Student student;  5  6     public Teacher (Student student) {  7         System.out.println("Teacher init1:" + student);  8  9     } 10 11     public void teach () { 12         System.out.println("teach:"); 13         student.learn(); 14     } 15 }
复制代码

        这种循环依赖没有什么解决办法,因为JVM虚拟机在对类进行实例化的时候,需先实例化构造器的参数,而由于循环引用这个参数无法提前实例化,故只能抛出错误。

        Spring解决的循环依赖就是指属性的循环依赖,如下所示:

复制代码
 1 @Service  2 public class Teacher {  3     @Autowired  4     private Student student;  5  6     public Teacher () {  7         System.out.println("Teacher init1:" + student);  8  9     } 10 11     public void teach () { 12         System.out.println("teach:"); 13         student.learn(); 14     } 15     16 }
复制代码
复制代码
 1 @Service  2 public class