| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Spring如何解决Bean的循环依赖? -> 正文阅读 |
|
[Java知识库]Spring如何解决Bean的循环依赖? |
什么是循环依赖?? ? ? ?在Spring中,对象不是new出来的,而是经历过一系列生命周期,通过依赖注入最终获得的。?循环依赖就是指多个bean之间的互相依赖,或者是自己注入自己的情况下,就比如A依赖于B,B依赖于C,C又依赖于A,这样就创造出了一个类似于先有鸡还是先有蛋的问题,造成系统崩溃。 ???????? ?Spring的循环依赖多发生在Spring容器注入的时候,且是单例。 如何解决循环依赖?? ? ? ? 从根本问题出发,打破循环,不让Bean循环! 那么Spring是怎么样实现的呢? ? ? ? ? 首先,单例Bean的初始化完成过程为有三个阶段 ? ? ? ? ①实例化;②属性赋值,③初始化 我们刚才所说的Spring容器注入主要发生在第①步初始化和②步属性赋值。所以我们要切入这个点去解决问题。 Spring解决单例循环依赖问题,使用了三级缓存 三级缓存:
每级缓存的大致意思作用 singletonFactories : 进入实例化阶段的单例对象工厂的cache (三级) earlySingletonObjects :完成实例化但是尚未初始化的,提前暴光的单例对象的Cache (二级) singletonObjects:完成初始化的单例对象的cache(一级) 我们创建Bean的时候,会先从cache缓存里找,这一部其实就是singletonObjects,它里面的犯法用到了三级缓存。 来看看他的主要方法
? ? ? ? Spring解决依赖循环主要就是靠这个三级缓存。 我们来分析一下 ????????“A的setter依赖了B的实例对象,同时B的setter依赖了A的实例对象”这种循环依赖的情况。 ????????A首先完成了初始化的第一步,并且将自己提前曝光到singletonFactories中,此时进行初始化的第二步,A发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走B的create流程。 ????????B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects(没有,此时A还没初始化完全),尝试二级缓存earlySingletonObjects(还是没有),尝试三级缓存singletonFactories,由于A通过ObjectFactory将自己提前曝光了,所以B能够通过ObjectFactory.getObject拿到A对象(虽然A还没有初始化完全,但是也可以获取到,虽然用不了),B拿到A对象后顺利完成了初始化阶段1、2、3,完全初始化之后将自己放入到一级缓存singletonObjects中。 ????????返回A中,A此时能拿到B的对象顺利完成自己的初始化阶段2、3,最终A也完成了初始化,进去了一级缓存singletonObjects中, ????????最后由于B拿到了A的对象引用,所以B现在也能获取到A对象,并完成了初始化。 最后说一下并不是所有单例Spring都能解决以来循环。 可以解决的单例:①都是setter注入,②都是属性注入,③一个B是setter注入,一个A是构造器注入(A中注入B(setter),B中注入A(构造器)) 不能解决的单例:①都是构造器注入,②一个A是setter注入,一个B是构造器注入(B中注入A,A中注入B) 原因是 Spring 在创建 Bean 时默认会根据自然排序进行创建,A 会先于 B 进行创建。 |
|
|
上一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/30 13:41:37- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |