zoukankan      html  css  js  c++  java
  • spring循环依赖问题

    一、循环依赖与加载类型、作用域的关系

    在开始介绍各种情况之前,首先要了解以下三个知识点:

    Spring中依赖注入的方式有两种,属性注入与构造器注入。上面的代码中,类A就是通过属性注入的方式注入了B,类B是通过构造器注入的方式注入了A。

    Spring中的bean根据作用域的不同,可以大体分为两类,singleton和prototype。singleton在一个容器中,只会有一个实例;而prototype在每次调用时,都会产生一个新的实例。

    Spring中,单例bean有延迟加载和立即加载两种加载方式,其中立即加载模式会在容器启动的时候就创建bean,而延迟加载会在容器启动后,使用到bean的时候再加载它。本篇分析一律使用延迟加载,因为有时候单例bean的加载顺序,会影响到创建bean的成功或失败。

     

    如果循环依赖的bean都是通过构造器注入依赖,那么不管它们是singleton还是prototype,都会失败。
    如果循环依赖的bean都是prototype,那么不管它们是通过构造器注入依赖还是通过属性注入依赖,都会失败。
    如果循环依赖的bean既有构造器注入也有属性注入,既有singleton也有prototype,在容器启动后,只有当获取的第一个bean是通过属性注入依赖的singleton时,才会成功,别的情况都会失败。
    所以最终结论就是:

    如果多个bean存在循环依赖,在Spring容器启动后,只有当获取的第一个bean是通过属性注入依赖的singleton时,才会成功,别的情况都会失败

    各种情况测试结果及分析:https://blog.csdn.net/chen2526264/article/details/80673598

    二、setting注入避免循环依赖的问题

    Spring容器启动后,如果我们去获取singletonA,那么容器的操作步骤大致如下:

    1、尝试创建bean singletonA,发现singletonA是singleton,且不是通过构造器注入依赖,那么先使用默认构造器创建一个A的实例,并保存对它的引用,并且将singletonA标记为“正在创建中的singleton”。然后发现singletonA依赖了singletonB,所以尝试创建singletonB。
    2、尝试创建bean singletonB,发现singletonB是singleton,且不是通过构造器注入依赖,那么先使用默认构造器创建一个B的实例,并保存对它的引用,并且将singletonB标记为“正在创建中的singleton”。然后发现singletonB依赖了singletonA,所以尝试创建singletonA。
    3、尝试创建singletonA,注意,这时Spring容器发现singletonA“正在创建中”,那么就不会再去创建singletonA,而是返回容器之前保存了的对singletonA的引用(首先会读取singletonObjects缓存中的实例,如果存在则直接返回。因为当我们实例化完成的时候,会通过addSingleton加入到缓存,所以Address注入User的时候不会重新加载一遍,只是从缓存中直接读取,所以不会有循环引用的问题)。


    4、容器将singletonA通过setter方法注入到singletonB,从而singletonB完成创建。
    5、容器将singletonB通过setter方法注入到singletonA,从而singletonA完成创建。

  • 相关阅读:
    Redhat7.x静默安装19C客户端
    利用增量备份修复DG备库中的gap>>>>>>>>>>>有新增数据文件
    利用增量备份修复DG备库中的gap>>>>>>>>>>>无新增数据文件
    ORA-01665 control file is not a standby control file
    ORA-01110 ORA-01122 ORA-01110 ORA-01200解决办法
    Zabbix5.0+Grafana可视化部署教程
    RedHat 7.5配置bonding双网卡绑定(转)
    11.2.0.1 RAC环境部分磁盘组无法自动挂载,导致数据库实例无法启动(转)
    11.2.0.1 RAC环境经典bug CRS-4124: Oracle High Availability Services startup failed.
    Git配置SSH及常用命令
  • 原文地址:https://www.cnblogs.com/anhaogoon/p/12554057.html
Copyright © 2011-2022 走看看