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日

相关文章

  • 开机提示配置文件已损坏将用临时文件进入的多种解决方法

    关于“开机提示配置文件已损坏将用临时文件进入”的多种解决方法,可以按以下步骤进行。 1. 重启电脑 当出现“开机提示配置文件已损坏将用临时文件进入”的提示时,首先建议尝试重启电脑。这是因为有可能是一次意外的系统错误导致了配置文件损坏,重启电脑后此问题可能会解决。 2. 使用“系统还原”恢复 如果重启电脑后仍然出现“开机提示配置文件已损坏将用临时文件进入”的问…

    other 2023年6月25日
    00
  • C语言中字符串常用函数strcat与strcpy的用法介绍

    标题:C语言中字符串常用函数strcat与strcpy的用法介绍 1. 简介 在C语言中,字符串是以一个字符数组的形式存储的。在对字符串进行各种操作时,常常需要用到字符串处理函数来完成操作。其中,strcat和strcpy函数是C语言中比较常用的字符串处理函数之一,本文即是要介绍这两个函数的用法。 1.1 strcat函数 函数原型:char *strcat…

    other 2023年6月20日
    00
  • Docker容器修改配置文件的实现

    下面是Docker容器修改配置文件的实现完整攻略: 1. 查看容器配置文件 首先需要进入Docker容器内部来查看需要修改的配置文件。有两种方式可以进入容器内部: 1.1. Docker attach命令 使用docker exec -it <container_name> /bin/bash命令进入容器,通过cd命令切换到配置文件所在的目录,使…

    other 2023年6月25日
    00
  • 深入了解Golang包的获取方法

    深入了解Golang包的获取方法 在Golang中,包是组织和复用代码的基本单元。本攻略将详细介绍获取Golang包的方法,包括标准库包和第三方包。 获取标准库包 Golang的标准库包是与Golang一起安装的包,可以直接使用。以下是获取标准库包的方法: 导入包:在代码中使用import语句导入需要的标准库包。例如,要使用fmt包,可以使用以下导入语句: …

    other 2023年10月13日
    00
  • Python学习之包与模块详解

    Python学习之包与模块详解 在Python中,包和模块是组织和管理代码的重要概念。本攻略将详细讲解包和模块的使用方法和区别。 包(Package) 包是一个包含多个模块的目录,用于组织和管理相关的模块。包是一个带有特殊__init__.py文件的目录。__init__.py文件可以为空文件,也可以包含包的初始化代码。 以下是包的一些特点和示例说明: 包需…

    other 2023年10月13日
    00
  • AE视频怎么分段渲染输出? ae导出单个或多个视频的教程

    标题:AE视频分段渲染输出攻略 什么是AE视频分段渲染输出? 在AE中,有些视频项目可能由于文件过大或过于复杂,导致在一次渲染中无法完成。这时就需要进行视频分段渲染输出,将较长的视频渲染成多个较短的细分视频,每个细分视频都可以自行进行渲染和输出。 怎么进行视频分段渲染输出? 步骤1:选择渲染队列面板 首先,在AE主界面选择上方的”窗口”菜单,找到”渲染队列”…

    other 2023年6月27日
    00
  • android调用web service(cxf)实例应用详解

    Android调用Web Service(CXF)实例应用详解 目录 前言 步骤 步骤一:创建 Web Service 步骤二:创建 Android 工程 步骤三:修改 AndroidManifest.xml 文件 步骤四:导入 CXF 库文件 步骤五:创建 Web Service 的代理类 步骤六:调用 Web Service 示例说明 示例 1:获取天气…

    other 2023年6月27日
    00
  • win7怎么打开后缀名为.pst的文件 win7系统文件后缀名.pst打开办法

    Win7系统文件后缀名.pst打开办法 如果你在Win7系统中遇到了后缀名为.pst的文件,下面是一些打开这种文件的方法: 方法一:使用Microsoft Outlook打开.pst文件 首先,确保你已经安装了Microsoft Outlook软件。如果没有安装,你可以从Microsoft官方网站下载并安装它。 打开Microsoft Outlook软件。 …

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