• 8、Bean的循环依赖问题


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

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

    比如:丈夫类Husband,妻子类WifeHusband中有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 是如何对应的

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

    注意:

    • 只有在scopesingleton的情况下,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对象

    注意:

    • 基于构造注入的方式下,产生的循环依赖也是无法解决的,所以编写代码时一定要注意
  • 相关阅读:
    spi.c、spi设备驱动以及spi控制器驱动
    Python 用相对名称来导入包中的子模块
    数据结构——二叉树
    如何去实现配置化页面 - 戴向天
    正式对标苹果,小米 12 系列三箭齐发,MIUI 欲成为跨设备操作系统
    通过http发送post请求的三种Content-Type分析
    frp内网穿透xtcp安全点对点p2p部署记录打洞失败解决方法
    13-Linux之rpm软件管理
    SCS【7】单细胞转录组之轨迹分析 (Monocle 3) 聚类、分类和计数细胞
    【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之数码管动态显示(五)
  • 原文地址:https://blog.csdn.net/qq_67720621/article/details/127826287