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

yizhihongxing

下面是对"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日

相关文章

  • Vue中图片上传组件封装-antd的a-upload二次封装的实例

    一、背景 在Vue项目中,我们经常会使用上传图片的功能,而Ant Design Vue提供了一个非常方便的组件——a-upload,但是它的样式和功能可能无法满足我们的需求。因此,我们需要对它进行二次封装,定制我们需要的功能和样式。 二、封装步骤 创建一个Upload组件,在里面引入a-upload组件。 <template> <a-upl…

    other 2023年6月25日
    00
  • springboot + vue 实现递归生成多级菜单(实例代码)

    下面我将为您详细讲解“springboot + vue 实现递归生成多级菜单”的完整攻略。 简介 本文将介绍如何使用SpringBoot和Vue.js实现递归生成多级菜单。通过该方案,可以生成任意深度的多级菜单。 准备工作 在开始之前,需要下载安装以下软件: JDK 8+ Node.js Vue CLI 创建SpringBoot项目 首先,使用Spring …

    other 2023年6月27日
    00
  • 基于Python利用Faker批量测试数据

    基于Python利用Faker批量生成测试数据攻略 Faker是一个Python库,用于生成各种类型的随机测试数据。以下是使用Faker库批量生成测试数据的完整攻略: 步骤1:安装Faker库 首先,确保您已经安装了Python。然后,使用pip命令安装Faker库: pip install faker 步骤2:导入Faker库 在Python脚本中导入Fa…

    other 2023年10月16日
    00
  • 怎么安装nslookup

    nslookup是一种用于查询DNS记录的命令行工具。如果您需要使用nslookup,可以按照以下步骤进行安装。以下是如何安装nslookup的完整攻略,包含两个示例说明。 步骤一:打开终端 在Windows上,打开命令提示符。在macOS或Linux上,打开终端。 步骤二:安装nslookup 在Windows上,nslookup是默认安装的。在macOS…

    other 2023年5月9日
    00
  • 微软:win10开发者应善用自适应磁贴与交互式通知功能

    微软推出的Windows 10操作系统中,自适应磁贴与交互式通知功能为开发者提供了更大的发挥空间,从而提高用户体验和开发效率。下面是详细的攻略说明: 什么是自适应磁贴 在Windows 10系统中,用户可以将各种应用程序的图标添加到开始菜单或右侧的开始屏幕中。这些图标就是磁贴。自适应磁贴将这些磁贴的显示效果进行了改进,让其能够根据用户设备屏幕的大小、分辨率和…

    other 2023年6月26日
    00
  • Flutter系统网络图片加载流程解析

    Flutter系统网络图片加载流程解析 Flutter系统提供了许多网络图片加载的功能,但是对于初学者来说,很难理解这些功能的原理和使用方法。本文将对Flutter系统网络图片加载的流程进行解析,并提供两个示例说明。 图片加载的流程 Flutter系统网络图片加载的流程大致如下: 根据图片的URL创建一个ImageProvider对象。 ImageProvi…

    other 2023年6月26日
    00
  • centos7忘记root密码解决方法

    centos7忘记root密码解决方法 在使用CentOS7系统时,忘记root用户的密码是一件很麻烦的事情。本文将介绍一些常用的解决方法。 方法一:单用户模式更改密码 重启电脑,在grub菜单下按’E’键进入编辑状态。 找到kernel行,并将其结尾处的“ro”改为“rw init=/sysroot/bin/sh”(注意不能删除原来的“ro”)。 按下Ct…

    其他 2023年3月28日
    00
  • elementui之封装下载模板和导入文件组件方式

    这里是关于 “elementui之封装下载模板和导入文件组件方式” 的完整攻略。 一、下载模板组件 对于 elementui,下载模板组件是一个十分常见的需求。我们可以使用 el-button 和 el-link 组件来实现。 首先,我们需要在组件中引入 Button 和 Link 组件。 import { Button, Link } from &quot…

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