【SSM】Spring6(六.Bean的循环依赖)
文章目录
- 1.Bean的循环依赖
- 2. singleton+setter的模式下产生的循环依赖
-
- 2.1 示例
- 2.2 spring可以自己解决的原因
- 3.prototype+setter的模式下产生的循环依赖
- 4.构造方法注入下产生的循环依赖问题
- 5.Spring解决循环依赖的机理
1.Bean的循环依赖
2. singleton+setter的模式下产生的循环依赖
2.1 示例
HusBand.java
package com.sdnu.spring6.bean;public class Husband {private String name;private Wife wife;public void setName(String name) {this.name = name;}public void setWife(Wife wife) {this.wife = wife;}public String getName() {return name;}@Overridepublic String toString() {return "Husband{" +"name='" + name + '\\'' +", wife=" + wife.getName() +'}';}
}
Wife.java
package com.sdnu.spring6.bean;public class Wife {private String name;private Husband husband;public void setName(String name) {this.name = name;}public void setHusband(Husband husband) {this.husband = husband;}public String getName() {return name;}@Overridepublic String toString() {return "Wife{" +"name='" + name + '\\'' +", husband=" + husband.getName() +'}';}
}
spring配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.sdnu.spring6.bean.Husband" id="husbandBean" scope="singleton"><property name="name" value="小明"/><property name="wife" ref="wifeBean"/></bean><bean class="com.sdnu.spring6.bean.Wife" id="wifeBean" scope="singleton"><property name="name" value="小丽"/><property name="husband" ref="husbandBean"/></bean>
</beans>
测试
package com.sdnu.spring6.test;import com.sdnu.spring6.bean.Husband;
import com.sdnu.spring6.bean.Wife;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class CircularDependency {@Testpublic void testCD(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");Husband husbandBean = applicationContext.getBean("husbandBean", Husband.class);System.out.println(husbandBean);Wife wifeBean = applicationContext.getBean("wifeBean", Wife.class);System.out.println(wifeBean);}
}
在singleton + set注入的情况下,循环依赖是没有问题的。Spring可以解决这个问题。
2.2 spring可以自己解决的原因
在这种模式下,spring对Bean的管理主要分为两个阶段:
(1)在spring容器加载的时候,实例化Bean,只要其中任意一个Bean实例化后,马上进行“曝光”
(2)Bean“曝光”后,再进行属性赋值(调用set方法)
3.prototype+setter的模式下产生的循环依赖
spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.sdnu.spring6.bean.Husband" id="husbandBean" scope="prototype"><property name="name" value="小明"/><property name="wife" ref="wifeBean"/></bean><bean class="com.sdnu.spring6.bean.Wife" id="wifeBean" scope="prototype"><property name="name" value="小丽"/><property name="husband" ref="husbandBean"/></bean>
</beans>
注意,只要两个Bean中有一个为singleton就不会产生循环依赖的问题。
4.构造方法注入下产生的循环依赖问题
通过构造方法注入产生了循环依赖,并且Spring是无法解决这种循环依赖的。
原因:主要原因是因为通过构造方法注入导致的:因为构造方法注入会导致实例化对象的过程和对象属性赋值的过程没有分离开,必须在一起完成导致的。
5.Spring解决循环依赖的机理
Bean都是单例的,我们可以先把所有的单例Bean实例化出来,放到一个集合当中(我们可以称之为缓存),所有的单例Bean全部实例化完成之后,以后我们再慢慢的调用setter方法给属性赋值。这样就解决了循环依赖的问题。