• 8、Bean的循环依赖问题


    1、 singleton下的set注入产生的循环依赖(解决)

    A对象中有B属性。B对象中有A属性。这就是循环依赖。我依赖你,你也依赖我。

    比如:丈夫类Husband,妻子类Wife。Husband中有Wife的引用。Wife中有Husband的引用。

    Husband

    @Data
    public class Husband {
        private String name;
        private Wife wife;
    
        @Override
        public String toString() {
            return "Husband{" +
                    "name='" + name + '\'' +
                    ", wife=" + wife.getName() +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Wife

    @Data
    public class Wife {
        private String name;
        private Husband husband;
    
        @Override
        public String toString() {
            return "Wife{" +
                    "name='" + name + '\'' +
                    ", husband=" + husband.getName() +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    springBean.xml

        
    	
        <bean id="husband" class="com.cjf.bean.Husband" scope="singleton">
            <property name="name" value="张三"/>
            <property name="wife" ref="wife"/>
        bean>
        <bean id="wife" class="com.cjf.bean.Wife" scope="singleton">
            <property name="name" value="小花"/>
            <property name="husband" ref="husband"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    test

    @Test
    public void testCD() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("springBean.xml");
        Husband husbandBean = applicationContext.getBean("husband", Husband.class);
        Wife wife = applicationContext.getBean("wife", Wife.class);
        System.out.println(husbandBean);
        System.out.println(wife);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20221110211610159

    该模式下,为什么循环循环依赖不会出现问题,Spring 是如何对应的

    • 主要原因是,在这中模式下Spring对Bean 的管理主要分为清晰的两个阶段
      • 第一个阶段:在Spring 容器加载的时候,实例化Bean,只要其中任意一个Bean实例化之后,马上进行" 曝 光 \color{red}曝光 曝光"【不等属性赋值曝光】
      • 第二个阶段:Bean “曝光”之后,在进行属性的赋值
    • 核心解决方案是:实例化对象和对象的属性赋值分为两个阶段来完成的
    • 就是 先实例化对象再给对象赋值

    注意:

    • 只有在scope 是singleton的情况下,Bean才会采取提的“察光的措施。

    2、prototype下的set注入产生的循环依赖

        
        <bean id="husband" class="com.cjf.bean.Husband" scope="prototype">
            <property name="name" value="张三"/>
            <property name="wife" ref="wife"/>
        bean>
        <bean id="wife" class="com.cjf.bean.Wife" scope="prototype">
            <property name="name" value="小花"/>
            <property name="husband" ref="husband"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    image-20221110214357841

    不断的相互new新的对象

    • 请求的 bean 目前正在创建中:是否有无法解析的循环引用?

    若其中一个是singleton,则不会出现出现问题

    <bean id="husband" class="com.cjf.bean.Husband" scope="singleton">
        <property name="name" value="张三"/>
        <property name="wife" ref="wife"/>
    bean>
    <bean id="wife" class="com.cjf.bean.Wife" scope="prototype">
        <property name="name" value="小花"/>
        <property name="husband" ref="husband"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    因为在husband创建后,setter进行赋值wife。会去创建一个新的wife对象,在进行husband赋值,直接获取之前的单例husband就是了

    3、 singleton下的构造注入产生的循环依赖

    
    <bean id="husband" class="com.cjf.bean.Husband" scope="singleton">
        <constructor-arg index="0" value="张三"/>
        <constructor-arg index="1" ref="wife"/>
    bean>
    <bean id="wife" class="com.cjf.bean.Wife" scope="singleton">
        <constructor-arg index="0" value="小花"/>
        <constructor-arg index="1" ref="husband"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在husband创建对象的时候,要给wife赋值,即去创建wife对象,wife对象创建的时候要给husband赋值,但是husband未曝光(husband还在创建过程中),所以wife对象得不到husband对象。所以wife对象也不会被曝光出来,导致husband对象得不到wife对象

    注意:

    • 基于构造注入的方式下,产生的循环依赖也是无法解决的,所以编写代码时一定要注意
  • 相关阅读:
    Linux- inode & vnode
    运营商三要素核验接口-手机实名验证API
    matlab, python串口10ms毫秒 连续发送16进制数组
    quartz笔记
    华为路由器多WAN口设置负载均衡
    JDK下载安装及环境配置
    C++中类的六个默认成员函数
    《XML 语言》教学上机实验报告
    VMWare不使用简易安装,手动安装ISO操作手册
    网络安全深入学习第八课——代理与端口转发
  • 原文地址:https://blog.csdn.net/qq_67720621/article/details/127826287