一. 什么是SpringIOC的三级缓存
类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。
如下图是三个类之间的循环依赖
Spring 的依赖注入方式有三种:构造方法注入、setter 方法注入、接口注入
- setter 方法注入的方式,是在对象实例化完成之后,再通过反射调用对象的 setter 方法完成属性的赋值,能够处理循环依赖的问题,也是本文要讲的
- 构造方法注入的方式,将实例化与初始化并在一起完成,能够快速创建一个可直接使用的对象,但它没法处理循环依赖的问题,类似先有鸡还是先有蛋的问题
- 接口注入的方式太灵活,易用性比较差,所以并未广泛应用起来
二. 跟着栗子看源码
下面这个栗子是两个类的相互依赖,同样能看出来三级缓存的流程
Animal类:
public class Animal {
private String name;
private Fruits fruits;
public Fruits getFruits() {
return fruits;
}
public void setFruits(Fruits fruits) {
this.fruits = fruits;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Fruits类:
public class Fruits {
private String name;
private Animal animal;
public Animal getAnimal() {
return animal;
}
public void setAnimal(Animal animal) {
this.animal = animal;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
SpringBean的XML配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
<bean id="fruits" class="com.jingchuan.model.Fruits">
<property name="name" value="banana"></property>
<property name="animal" ref="animal"></property>
</bean>
<bean id="animal" class="com.jingchuan.model.Animal">
<property name="name" value="monkey"></property>
<property name="fruits" ref="fruits"></property>
</bean>
</beans>
测试:
import com.jingchuan.model.Fruits;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestIoc {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationIoc.xml");
Fruits fruits = (Fruits) context.getBean("fruits");
System.out.println(fruits.getName());
}
}
上面的测试代码配了两个Bean:Fruits
和Animal
,他们相互依赖对方