Spring循环依赖问题的解决
循环依赖问题
一个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循环依赖问题的解决的更多相关文章
- spring循环依赖是怎么解决的?
回答:循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleA,则它们最终反映为一个环. Spring如何解决循环依赖? ...
- Spring循环依赖的三种方式以及解决办法
一. 什么是循环依赖? 循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环.比如A依赖于B,B依赖于C,C又依赖于A.如下图: 注意,这里不是函数的循环调用,是对象的 ...
- Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)
本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...
- Spring循环依赖的解决
## Spring循环依赖的解决 ### 什么是循环依赖 循环依赖,是依赖关系形成了一个圆环.比如:A对象有一个属性B,那么这时候我们称之为A依赖B,如果这时候B对象里面有一个属性A.那么这时候A和B ...
- Spring循环依赖问题
什么是循环依赖? 循环依赖就是循环引用,指两个或多个bean互相持有对方,比如说TestA引用TestB.TestB引用TestA,最终形成一个闭环. 注意:循环依赖不是指循环调用. 循环调用:指方法 ...
- Spring循环依赖
Spring-bean的循环依赖以及解决方式 Spring里面Bean的生命周期和循环依赖问题 什么是循环依赖? 循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环. ...
- Spring 循环依赖
循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不 ...
- Springboot源码分析之Spring循环依赖揭秘
摘要: 若你是一个有经验的程序员,那你在开发中必然碰到过这种现象:事务不生效.或许刚说到这,有的小伙伴就会大惊失色了.Spring不是解决了循环依赖问题吗,它是怎么又会发生循环依赖的呢?,接下来就让我 ...
- 这个 Spring 循环依赖的坑,90% 以上的人都不知道
1. 前言 这两天工作遇到了一个挺有意思的Spring循环依赖的问题,但是这个和以往遇到的循环依赖问题都不太一样,隐藏的相当隐蔽,网络上也很少看到有其他人遇到类似的问题.这里权且称他非典型Spring ...
随机推荐
- certutil绕过
一般进内网过后我都会使用certutil下载文件,但在最近打一台内网机子的时候出现了certutil拒绝访问的情况,在本地搭建了一个环境尝试绕过certutil下载文件. 安装杀软更新到最新版本,开启 ...
- 从I/O多路复用到Netty,还要跨过Java NIO包
本文是Netty系列第4篇 上一篇文章我们深入了解了I/O多路复用的三种实现形式,select/poll/epoll. 那Netty是使用哪种实现的I/O多路复用呢?这个问题,得从Java NIO包说 ...
- Android 系统开发做什么?
题外话 18 年我从 Android 应用开发转 Framework 层开发了,从此开启了 996 幸福生活,博客技术文更新基本停滞了,被工作占据了过多的精力,实在没时间像以前一样拟稿.写作,实践.反 ...
- Android学习之CoordinatorLayout+AppBarLayout
•AppBarLayout 简介 AppbarLayout 是一种支持响应滚动手势的 app bar 布局: 基本使用 新建一个项目,命名为 TestAppBarLayout: 修改 activity ...
- 基于gitlab的项目管理流程
框架 背景 个人是不太愿意使用用户体验差的软件来做项目管理,行业内,要找到这么一款软件,又要符合自己的需求,着实不容易.要免费,易用性要好,要安全,要有数据统计.而程序员的世界,SVN 之后,可能没有 ...
- B1029/A1048 旧键盘损坏了,在输入一段文字时坏了的键不可以正常使用,现给出应输入的一段文字,和实际输出的文字,找出坏掉的键。
#include<cstdio> #include<cstring> const int maxn = 1000; bool HashTable[maxn] = { false ...
- pwnable.tw 3x17
3x17 文章主要是参考了https://xuanxuanblingbling.github.io/ctf/pwn/2019/09/06/317/ 首先我们检查一下开启的保护 运行一下,先让输入add ...
- linux安装cmake
1 概述 linux下安装cmake,目前最新的版本为3.17.0-rc2,安装的方式一共有三种:通过软件包仓库安装,通过编译好的版本进行安装,从源码手动编译安装. 2 仓库安装 笔者的是deepin ...
- Mysql之读写分离架构-Atlas
Atlas介绍 1.png Atlas是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目. 它是在mysql-proxy 0.8.2版本的基础上, ...
- B - 真·签到题 FZU - 2214(背包)
Given a set of n items, each with a weight w[i] and a value v[i], determine a way to choose the item ...