Spring源码之循环依赖之三级缓存详解

下面是对"Spring源码之循环依赖之三级缓存详解"的完整攻略:

什么是循环依赖

循环依赖指的是对象之间出现相互依赖的情况,通常是两个或多个对象互相持有对方的引用,从而导致它们之间出现循环依赖的问题。在Spring框架中,循环依赖的问题通常在bean的创建过程中出现。

三级缓存解决循环依赖问题

Spring框架为了解决bean之间的循环依赖问题,设计了三级缓存机制,其中包含singletonObjects、earlySingletonObjects和singletonFactories三个缓存:

  • singletonObjects缓存是最终保存已经构造完成的bean的缓存,用于存储所有的单例bean实例。
  • earlySingletonObjects缓存是正在创建或已经创建完成但是没有完成其他bean之间注入的bean的缓存,它保存的是还未完全创建完成的实例,即在bean实例化过程中就已经被加入earlySingletonObjects缓存中,它们是被Spring容器创建过的但是还未完全实例化完毕,不能被其他的bean注入。
  • singletonFactories缓存是用于存储创建中的bean工厂的,它主要保存的是一些提供beanObjectFactory方便其他bean属性注入、实例化时需要的函数来创建bean的缓存对象。

这三个缓存之间共同协作,优先依次检查earlySingletonObjects、singletonFactories和singletonObjects三个缓存,建立和获取bean,直到最终创建完成。

Spring循环依赖解决机制的详细过程

当我们向Spring容器中添加一个bean时,Spring容器会首先检查singletonObjects缓存是否存在该bean,若存在,则直接返回缓存中的bean,否则,则继续检查earlySingletonObjects缓存是否存在该bean。

若earlySingletonObjects缓存中没有该bean,则继续检查singletonFactories缓存是否存在该bean。若存在,则依据singletonFactories实例化并初始化bean,并将新的bean实例放到earlySingletonObjects缓存中。

若earlySingletonObjects缓存中存在该bean,则说明当前bean正在创建过程中且已经存在循环依赖,那么将会返回早期的bean实例,并根据链表追加属性。

若singletonFactories缓存中没有该bean,则说明bean还没有被创建。此时Spring会继续实例化并初始化该bean,并将生成的bean实例放到earlySingletonObjects缓存中,同时生成该bean对应的beanFactory方法工厂。在初始化期间,生成bean的属性时会走子属性,如果子属性是一个已经创建完成的单例实例,那么就会使用singletonObjects中的实例。最后,Spring会将生成的bean实例放到singletonObjects缓存中,从而成功解决了循环依赖的问题。

示例说明

为了更好地理解Spring的三级缓存机制,假设我们有两个依赖关系为b -> a,即b依赖于a的bean。 模拟过程如下:

  1. Spring容器从singletonObjects缓存中查找b的实例。因为它还没有创建,因此singletonObjects缓存没有查找到b的实例。
  2. Spring容器继续从earlySingletonObjects查找b的实例。earlySingletonObjects缓存中没有b实例。
  3. Spring容器从singletonFactories查找b的beanFactory。找到了对应的beanFactory,使用beanFactory创建b实例,并将b的实例放入到earlySingletonObjects缓存中。
  4. Spring容器创建a实例时,需要使用b实例作为依赖注入的属性,而此时b的实例还没有完全初始化,因此Spring容器会返回一个b的代理对象。
  5. Spring容器继续创建b实例,发现b依赖于a的bean,因此需要从singletonObjects中获取a的实例。
  6. 但是此时a的实例还没有完全初始化,因此Spring容器会返回a的代理对象。
  7. Spring容器继续初始化a实例,并将最终的a实例放入到singletonObjects缓存中。
  8. Spring容器接着初始化b实例,将最终的b实例放入到singletonObjects缓存中并完成b实例化。

在这个示例中,a实例是首先被初始化的,而b实例是在a完成初始化后才被初始化的,通过三级缓存机制确保了b的代理对象能够顺利地依赖于a。这就是Spring框架解决循环依赖的机制。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring源码之循环依赖之三级缓存详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • C语言中斐波那契数列的三种实现方式(递归、循环、矩阵)

    C语言中斐波那契数列的三种实现方式(递归、循环、矩阵) 斐波那契数列是指数列:1、1、2、3、5、8、13、21、…… 在数学上,斐波那契数列是以递归的方法来定义的,首两项为 1,之后每一项都是其前两项之和,即:F(1) = 1, F(2) = 1F(n) = F(n-1) + F(n-2) , n > 2 递归实现 递归是最贴近人类思维的一种算法实现…

    other 2023年6月27日
    00
  • Web移动端Fixed布局的解决方案

    Web移动端Fixed布局主要是为了在移动端上实现固定定位,使得页面元素固定在页面指定位置不会跟随页面滚动而发生变化。但是,在某些情况下,Fixed布局会给开发和设计带来很大的困扰,如在iOS上Fixed布局时,可能会出现滑动空白区域无法回到原来Fixed定位的位置的问题,这就需要我们在开发时寻找一种更加灵活的解决方案。下面是Web移动端Fixed布局解决方…

    other 2023年6月26日
    00
  • jQuery实现选项卡嵌套效果

    jQuery实现选项卡嵌套效果攻略 选项卡嵌套效果是一种常见的网页交互效果,可以让用户在多个层级的选项卡之间进行切换。在本攻略中,我们将使用jQuery库来实现这个效果。下面是详细的步骤和示例说明。 步骤一:HTML结构 首先,我们需要创建一个合适的HTML结构来容纳选项卡和对应的内容。以下是一个简单的示例: <div class=\"tab…

    other 2023年7月27日
    00
  • android中的常用尺寸单位(dp、sp)快速入门教程

    以下是关于“Android中的常用尺寸单位(dp、sp)快速入门教程”的完整攻略,包括基本概念、使用方法和两个示例。 基本概念 在Android中常用的尺寸单位有dp和sp。dp是density-independent pixel(密度无关像素)的缩写,它是一种基于屏幕密度的抽象单位,可以保证在不同的屏幕密度下,UI元素的大小和位置保持一致。sp是scale…

    other 2023年5月7日
    00
  • Git用户签名的修改取消及优先级拓展教程

    Git用户签名的修改取消及优先级拓展教程 在使用Git时,用户签名是用于标识提交代码的作者的信息,包括用户名与电子邮件地址。在某些情况下,我们可能需要修改或取消默认的用户签名。本文将详细讲解如何进行用户签名的修改和取消以及优先级拓展的操作。 查看当前用户签名信息 首先,我们需要查看当前用户签名信息,可通过以下命令实现: git config user.nam…

    other 2023年6月27日
    00
  • node.js(基础四)_express基础

    以下是node.js(基础四)_express基础的完整攻略,包括基本概念、使用方法、示例说明和注意事项。 基本概念 Express是一个基于Node.js的Web应用程序框架,它提供了一组强大的特性和工具,可以帮助开发人员更快速地构建Web应用程序。Express提供了路由、中间件、模板引擎等功能,可以帮助开发人员更高效地进行Web开发。 使用方法 以下是…

    other 2023年5月6日
    00
  • python的sys的append的../

    当然,我可以为您提供有关“python的sys的append的../”的完整攻略,以下是详细说明: 什么是Python的sys的append的../? 在Python中sys.path是一个包含模块搜索路径的列表。当Python解释器在导入模块,会按照sys.path中的路径序搜索模块。sys.path中的路径可以通过sys.path.append()方法进…

    other 2023年5月7日
    00
  • 图片加载进度实时显示

    一、概述 在网页中加载图片是很常见的场景,但一些大图片、网络延迟等因素都会导致图片加载时间延长。在用户等待图片加载时,为了提升用户体验,可以通过实时显示图片加载进度来让用户了解当前图片加载的进度,从而缓解用户的焦虑感和等待时间。本文将详细介绍如何实现图片加载进度实时显示的功能。 二、实现方式 实时显示图片加载进度的方式一般有两种,分别是:使用canvas绘制…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部