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日

相关文章

  • Excel表格Ctrl+E都有哪些功能 Excel表格Ctrl+E功能介绍

    Excel表格Ctrl+E功能介绍 在Excel表格中,Ctrl+E是一个常用的快捷键,它提供了一些有用的功能。下面是Ctrl+E的功能介绍: 1. 快速选择当前区域 按下Ctrl+E快捷键后,Excel会自动选择当前区域。这对于快速选定一大块数据非常有用。例如,你可以使用Ctrl+E来选择一个表格中的整个列或行。 示例说明: 假设你有一个包含数据的表格,你…

    other 2023年8月5日
    00
  • Android 拍照后返回缩略图的两种方法介绍

    当使用Android开发拍照功能时,可以通过两种方法获取拍照后的缩略图。下面将详细介绍这两种方法,并提供示例说明。 方法一:使用Camera API 首先,在AndroidManifest.xml文件中添加相机权限: <uses-permission android:name=\"android.permission.CAMERA\&quot…

    other 2023年9月7日
    00
  • C++读取文件的四种方式总结

    当我们需要读取文件时,可以使用以下四种方式: 1. 使用 C++ 标准库库函数 我们可以使用 ifstream 类和其对象读取文件内容,需要包含头文件 <fstream>。 #include <fstream> #include <iostream> using namespace std; int main() { if…

    other 2023年6月26日
    00
  • linux awk 字符串连接操作(字符串转数字,数字转字符串)

    Linux awk 是一款常用的文本处理工具,它可以方便地对文本文件进行操作和处理。字符串连接操作常用于将多个字符串拼接成一个字符串,或将字符串与数字之间进行转换。 字符串连接操作 在 awk 中,字符串连接可以使用双引号来实现,例如: $ awk ‘BEGIN{str1="Hello, "; str2="world!&quot…

    other 2023年6月20日
    00
  • Android 开发使用Activity实现加载等待界面功能示例

    针对“Android 开发使用Activity实现加载等待界面功能示例”的完整攻略,我将分以下几个步骤进行详细讲解: 创建等待界面布局文件 创建等待界面Activity并绑定布局文件 在需要创建等待界面的Activity中调用等待界面Activity 通过Handler消息机制关闭等待界面Activity 下面我将分别对以上几个步骤进行具体讲解。 1. 创建…

    other 2023年6月25日
    00
  • Win10 RS2更新了什么?Win10 RS2最终版本号1704首曝

    Win10 RS2更新了什么? Win10 RS2最终版本号1704首曝攻略 Win10 RS2是指Windows 10的第二个大型更新,也被称为“创意者更新”(Creators Update)。该更新引入了一系列新功能和改进,以提升用户体验和增强系统功能。下面是Win10 RS2更新的一些主要亮点: 1. 3D创作工具 Win10 RS2引入了一套强大的3…

    other 2023年8月2日
    00
  • win10 cmd提示不是内部或外部命令怎么办 三种方法修复错误提示

    下面是对于“win10 cmd提示不是内部或外部命令怎么办”的完整攻略。 1. 问题说明 在使用 Windows 10 中的命令提示符时,如果你输入了某些在系统中不存在的命令,就会出现类似于“不是内部或外部命令,也不是可运行的程序或批处理文件”等错误提示。这表明你输入的命令不存在或者路径配置不正确。 2. 解决方法 下面介绍三种常见的解决方法: 2.1 添加…

    other 2023年6月27日
    00
  • qt多线程使用qtcpsocket

    Qt多线程使用QTcpSocket 在使用Qt网络编程实现TCP通信时,经常需要使用多线程来处理网络连接,这样可以避免GUI线程被阻塞。本文将介绍如何使用Qt多线程和QTcpSocket进行带有连接池的TCP通信,以提高网络连接的效率。 连接池的概念 在实际应用中,服务器可能需要同时处理多个客户端的连接请求,并且客户端连接的数量是动态变化的。为了充分利用服务…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部