循环依赖问题

一个bean的创建分为如下步骤:

当创建一个简单对象的时候,过程如下:

  • 先从单例池中获取bean,发现无 a
  • 创建 a 的实例
  • 为 a 赋值
  • 把 a 放到单例池中

当创建一个对象并且其中有另外一个对象是就变成了这样:

但是当在B对象中由引用了A对象,就会变成这样:

因为A和B两者相互引用,但是单例池中始终无法创建任一对象,所以会出现死循环。

因此,我们需要添加一个半成品池,先把A初始化出来,放到一个半成品池中。

过程如下:

  • 先从单例池中找A对象,没有则开始创建A对象
  • 实例化A对象,并放入半成品池中
  • 为A对象赋值
  • 赋值时发现引用了B对象 --> 实例化B对象,并放入半成品池中
  • 为B对象赋值
  • 赋值时发现引用了A对象,从单例池中和半成品池中找A对象,并将其赋值
  • 实例化B对象,并放入单例池中
  • 实例化A对象,从半成品池中移除A对象,并放入单例池中

这样就解决了死循环创建但是当使用了动态代理后,情况又会有所变化.

先来看一下AOP的执行过程,如图:

在bean的创建过程中,创建动态代理的时机是在初始化之后的,如图:

这个时候半成品池里放的是没有代理过的A对象,当B去半成品池中获取A对象,获取的是动态代理前的A对象,而我们应该获取的是动态代理后的A对象,这就会出现问题.

为了解决AOP的问题,spring又加入了一个工厂池

执行过程如下:

  • 当创建A对象的时候会在工厂池中创建factory(a)
  • ....
  • 当给B赋值时,发现引用了A,就会去工厂池中执行getEarlyReference 提前处理方法,生成一个动态代理后的A对象,并放入半成品池中,再赋值给B
  • ...

注意:

​ 当实例化对象A的时候,A对象会产生与之对应的factory(a)方法,只有当某个对象引用A对象时,factory(a)方法才会被执行,从而去通过提前引用的方式创建动态代理对象放入半成品池中

如果说A对象没有被提前引用,factory(a)方法不会执行

Spring循环依赖问题的解决的更多相关文章

  1. spring循环依赖是怎么解决的?

    回答:循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleA,则它们最终反映为一个环. Spring如何解决循环依赖? ...

  2. Spring循环依赖的三种方式以及解决办法

    一. 什么是循环依赖? 循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环.比如A依赖于B,B依赖于C,C又依赖于A.如下图: 注意,这里不是函数的循环调用,是对象的 ...

  3. Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)

    本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...

  4. Spring循环依赖的解决

    ## Spring循环依赖的解决 ### 什么是循环依赖 循环依赖,是依赖关系形成了一个圆环.比如:A对象有一个属性B,那么这时候我们称之为A依赖B,如果这时候B对象里面有一个属性A.那么这时候A和B ...

  5. Spring循环依赖问题

    什么是循环依赖? 循环依赖就是循环引用,指两个或多个bean互相持有对方,比如说TestA引用TestB.TestB引用TestA,最终形成一个闭环. 注意:循环依赖不是指循环调用. 循环调用:指方法 ...

  6. Spring循环依赖

    Spring-bean的循环依赖以及解决方式 Spring里面Bean的生命周期和循环依赖问题 什么是循环依赖? 循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环. ...

  7. Spring 循环依赖

    循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不 ...

  8. Springboot源码分析之Spring循环依赖揭秘

    摘要: 若你是一个有经验的程序员,那你在开发中必然碰到过这种现象:事务不生效.或许刚说到这,有的小伙伴就会大惊失色了.Spring不是解决了循环依赖问题吗,它是怎么又会发生循环依赖的呢?,接下来就让我 ...

  9. 这个 Spring 循环依赖的坑,90% 以上的人都不知道

    1. 前言 这两天工作遇到了一个挺有意思的Spring循环依赖的问题,但是这个和以往遇到的循环依赖问题都不太一样,隐藏的相当隐蔽,网络上也很少看到有其他人遇到类似的问题.这里权且称他非典型Spring ...

随机推荐

  1. 【linux】系统编程-4-共享内存

    目录 前言 6. 共享内存 6.1 概念 6.2 操作函数 6.2.1 shmget() 6.2.2 shmat() 6.2.3 shmdt() 6.2.4 shmctl() 6.3 例子 参考: 前 ...

  2. 通俗易懂,android是如何管理内存的

    封面来源:https://medium.com/android-news/android-performance-patterns-rescue-tips-8c1e4c7cb1f0 前言 很高兴遇见你 ...

  3. Logback简介及配置文件logback.xml详解

    logback简介及配置文件说明 @author:wangyq @date:2021年3月31日 logback简介 ​ Logback是由log4j创始人设计的另一个开源日志组件,官方网站: htt ...

  4. java例题_37 有 n 个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 3 问最后留下的是原来第几号的那位。

    1 /*37 [程序 37 报数] 2 题目:有 n 个人围成一圈,顺序排号.从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子, 3 问最后留下的是原来第几号的那位. 4 */ 5 ...

  5. 力扣 - 560. 和为K的子数组

    目录 题目 思路1(前缀和) 代码 复杂度分析 思路2(前缀和+哈希表优化) 代码 复杂度分析 题目 560. 和为K的子数组 思路1(前缀和) 构建前缀和数组,可以快速计算任意区间的和 注意:计算区 ...

  6. java面试-JVM内存结构

    一.JVM内存结构 二.类加载(classLoader)机制 java中的ClassLoader详解 java类加载机制面试题 java类加载机制面试题 虚拟机把描述类的数据从Class文件加载到内存 ...

  7. 北航OO第一单元作业总结(1.1~1.3)

    经过了三次作业之后,OO第一单元告一段落,作为一个蒟蒻,我初步了解了面向对象的编程思想,并将所学内容用于实践. 一.第一次作业 1.架构分析 本次作业需要完成的任务为简单多项式导函数的求解.表达式仅支 ...

  8. 「一站式」兼容所有云厂商文件存储Spring Boot 实现

    背景 在互联网发展的今天,近乎所有的云厂商都提供对象存储服务.一种海量.安全.低成本.高可靠的云存储服务,适合存放任意类型的文件.容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本. 当我们 ...

  9. Spring/SpringBoot整合QuartZ

    https://www.bilibili.com/video/av55637917/?p=2

  10. GO-05-数据类型

    基本数据类型: 整型.浮点型 float32 float64.复数型(数学中的复数).布尔型.字符串.字符(byte.rune). 复合数据类型: 数组(array).切片(slice).映射(map ...