spring是创建实例的时候,是如何解决循环依赖的呢?
先来看一下isSingleton的实例getBean的整个流程:

步骤一

sharedInstance = getSingleton(name)

  1. 来获取缓存的单例实例
    (来源两处,参见图中同色系框框,
    一、单例创建完了会缓存一份singletonObjects; 
    二、创建过程中会缓存一份singletonFactories,创建完了删除)

  2. 如果能够获取得到,则直接返回bean

  3. 如果获取不到,则走getSingleton来实例化单例(参见步骤二)

步骤二

getSingleton(name)

  1. 将自身加singletonsCurrentlyInCreation(正在创建的单例容器)中

  2. 执行createBean方法(步骤三)

  3. 将自身从singletonsCurrentlyInCreation(正在创建的单例容器)中移除

  4. 创建的单例实例加入到单例缓存singletonObjects中

步骤三

createBean方法

  1. 通过构造函数创建实例

  2. 如果是单例 & 允许循环依赖&

    该bean在singletonsCurrentlyInCreation(正在创建的单例容器)中,则将上述创建的实例缓存到singletonFactories

  3. populatBean依赖注入属性,如果属性是beanName,则调用getBean回到开头

假设spring没有去解决循环依赖的问题,假设新建如下两个类:

 1@Component2public class A {34    @Autowired5    private B b;678    public A() {9        System.out.println("A Constructor");
10    }
11
12    @Override
13    public String toString() {
14        return "A{}";
15    }
16}1@Component2public class B {34    @Autowired5    private A a;678    public B() {9        System.out.println("B Constructor");
10    }
11
12
13    @Override
14    public String toString() {
15        return "B{}";
16    }
17}

那么,在创建A的单例的过程中,需要依赖注入B,转而去创建B,B的创建过程中又要依赖注入A,此时A在beanFactory中不存在,转而又去创建A,这样会形成一种死循环。
问题的解决办法,就是要在创建过程中,有一条分支路线能够终止创建过程并且返回对象。

spring是怎么解决循环依赖的呢?
在创建一个单例的过程中,一旦通过构造函数创建了一个实例,就将中间过程的实例对象暂时缓存起来。
--> 创建A① 
--> 执行到步骤三的第2步时,会将刚刚通过构造函数新建的实例缓存起来
--> 执行步骤三的第3步,依赖注入B,去创建B 
--> B又依赖注入A,创建A 
--> 步骤一中能直接从缓存singletonFactories获取到对象 return a
--> invoke b.setA(a) 
--> return B 
--> invoke a.setB(b) 
--> return A

以上

更多源码分析,关注公众号???

转载于:https://www.cnblogs.com/mianteno/p/10692633.html

[spring] 源码简析 如何解决循环依赖?相关推荐

  1. Spring 源码总结、IOC、循环依赖、AOP分析

    Spring 源码 本文基于 jdk 11 核心类 interface BeanFactory 该接口是访问 Spring bean 容器的根接口,是 bean 容器的基本客户端视图: 其他接口如Li ...

  2. spring源码解析(五) 循环依赖

    1.什么是循环依赖? Bean A → Bean B → Bean A 在A对象生命周期中注入B,进入B生命周期找A,但A还不存在,继续进入A对象生命周期找B,这就是循环依赖. 2.循环依赖造成的结果 ...

  3. spring源码阅读笔记09:循环依赖

    前面的文章一直在研究Spring创建Bean的整个过程,创建一个bean是一个非常复杂的过程,而其中最难以理解的就是对循环依赖的处理,本文就来研究一下spring是如何处理循环依赖的. 1. 什么是循 ...

  4. Spring源码解析-三级缓存与循环依赖,nginx架构图

    两个流程理论上是互不影响的 protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @N ...

  5. Spring-bean的循环依赖以及解决方式___Spring源码初探--Bean的初始化-循环依赖的解决

    本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可以应用在我们实际开发项目中. 什么是循环依赖? 怎么检测循环依赖 Spring怎么解决循环依赖 S ...

  6. Spring Boot源码简析 @EnableTransactionManagement

    相关阅读 Spring Boot源码简析 事务管理 Spring Boot源码简析 @EnableAspectJAutoProxy Spring Boot源码简析 @EnableAsync Sprin ...

  7. spring源码刨析总结

    spring源码刨析笔记 1.概述 spring就是 spring Framework Ioc Inversion of Control(控制反转/反转控制) DI Dependancy Inject ...

  8. ffmpeg实战教程(十三)iJKPlayer源码简析

    要使用封装优化ijk就必须先了解ffmpeg,然后看ijk对ffmpeg的C层封装! 这是我看ijk源码时候的笔记,比较散乱.不喜勿喷~ ijk源码简析: 1.ijkplayer_jni.c 封装的播 ...

  9. Log-Pilot 源码简析

    Log-Pilot 源码简析 简单介绍 源码简析 Pilot结构体 Piloter接口 main函数 Pilot.Run Pilot.New Pilot.watch Pilot.processEven ...

  10. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

最新文章

  1. Camera+销量突破200万 创始人分享成功经验
  2. boost源码剖析之:Tuple Types(rev#2)
  3. UITableView 自带编辑删除 自己定义button
  4. idea apollo启动VM参数设置
  5. linux安装redis有什么用吗,Linux下 安装Redis
  6. Django(ORM常用字段)
  7. 单表查询 多表查询 子查询
  8. Windows系列服务器上配置JSP运行环境,以及网站上线
  9. 税务系统什么时候使用计算机,2020年税务师考试题量、答题要求及计算器使用规定...
  10. Arduino(c) 16进制转字符串
  11. Android 包大小优化总结
  12. 无向有权图的建立(邻接链表法) 广度优先搜索 深度优先搜素
  13. 全新来客码智能纳客营销系统免费使用功能效果
  14. Extracting and Composing Robust Features with Denoising Autoencoders论文笔记
  15. 51“motorrr”寻迹小车学习1电机和寻迹模块
  16. 尘埃粒子计数器帮助实时监测半导体车间空气中的粒子数
  17. Java数据结构告诉你如何选用数据集合(2)顺序表
  18. Windows远程桌面连接不上问题
  19. STM32 RTC LSE 初始化失败 卡在 RTC_ICSR_INITF 或者 LSERDY
  20. odoo小程序商城概览(睿鸥商城)

热门文章

  1. python全栈脱产第20天------常用模块---re模块和subprocess模块
  2. RobotFramework自动化测试框架-移动手机自动化测试Clear Text关键字的使用
  3. UVA10317- Equating Equations(回溯+剪枝)
  4. [转]刚成为程序员的你需要什么技能
  5. 危险无处不在 Html标签带来的安全隐患
  6. jmeter 压测之动态数据关联
  7. [luoguP3332] [ZJOI2013]K大数查询(树套树)
  8. zjufantasy.com开发日记(1)
  9. 原型与继承学习笔记3
  10. Android Studio单元测试入门