循环依赖问题

一个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. 3、MyBatis教程之CURD操作

    4.CURD操作 1.查询 根据用户 Id查询用户 在UserMapper中添加对应方法 public interface UserMapper { List<User> getUserL ...

  2. RabbitMQ 入门 (Go) - 1. 简介和安装

    Message Broker(消息代理) 维基百科对 Message Broker 的定义是:Message broker 是一种中介程序模块,它把消息从发送方的正式消息传递协议转化为接收方的正式消息 ...

  3. 前端vue使用高德地图

    首先,注册Key 1.注册开发者账号,成为高德开放平台开发者 2.登陆之后,在进入「应用管理」 页面「创建新应用」 3.为应用添加 Key,「服务平台」一项请选择「 Web 端 ( JSAPI ) 」 ...

  4. Macbook 安装kali linux 双系统 2020.3 超详细

    博主折腾了一星期这东西,到现在都还有些坑没解决(最后面会讲).不过最起码系统装上了,可以用了,看到这桌面惊艳了,再点下左上角表示人间值得. 其实我是装了windos 10.macos 和kali三系统 ...

  5. CI/CD版本回滚Jenkins解决方案

    一.创建项目 填写项目名,关系到项目路径对应请谨慎命名 二.项目配置 1.配置字符串参数和选项参数 2.代码仓库配置 3.构建环境 4.构筑脚本配置 5.点击左下方的保存或者应用 三.使用方法 1.发 ...

  6. 博文推荐|多图详解 Apache Pulsar 消息存储模型

    关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息.存储.轻量化函数式计算为一体,采用计算与存储分离架构设计,支 ...

  7. 灵雀云Istio技术实践专题整理

    Istio技术实践专题(1) Service Mesh Istio 基本概念和架构基础 Istio被称作Kubernetes的最佳云原生拍档.从今天起,我们推出"Istio技术实践" ...

  8. 翻译:《实用的Python编程》08_02_Logging

    目录 | 上一节 (8.1 测试) | 下一节 (8.3 调试) 8.2 日志 本节对日志模块(logging module)进行简单的介绍. logging 模块 logging 模块是用于记录诊断 ...

  9. Asp.Net Core 5 REST API 使用 JWT 身份验证 - Step by Step

    翻译自 Mohamad Lawand 2021年1月22日的文章 <Asp Net Core 5 Rest API Authentication with JWT Step by Step> ...

  10. 算法很美,听我讲完这些Java经典算法包你爱上她

    大家好,我是小羽. 对于编程来说的话,只有掌握了算法才是了解了编程的灵魂,算法对于新手来说的话,属实有点难度,但是以后想有更好的发展,得到更好的进阶的话,对算法进行系统的学习是重中之重的. 对于 Ja ...