当前位置: 首页 > news >正文

Spring 三级缓存

文章目录

    • Spring 三级缓存
      • Spring 中循环依赖的现象
      • 三级缓存的作用
      • 三级缓存对象
      • 三级缓存工作流程
        • 操作三级缓存的核心源码
        • 三级缓存处理循环依赖的流程
      • 理解三级缓存——singletonFactories
      • Spring 二级缓存与三级缓存的区别及三级缓存的设计意义
        • 二级缓存与三级缓存的本质区别
        • 为什么需要三级缓存(而不只是二级缓存)

Spring 三级缓存

Spring 中循环依赖的现象

1、构造器循环依赖

  • 构造器循环依赖指的是在 Bean 的构造函数中存在相互依赖的情况。当 Spring 容器在创建 Bean 时,会先调用构造函数来实例化对象。如果存在构造器循环依赖,就会陷入一个死循环,因为创建一个 Bean 需要先创建另一个 Bean,而创建另一个 Bean 又需要先创建第一个 Bean。Spring 无法解决这种循环依赖,会直接抛出 BeanCurrentlyInCreationException 异常。

2、field 属性注入循环依赖

  • 单例(singleton)scope 下 setter 方法的循环依赖:单例 Bean 在 Spring 容器中只会创建一个实例。对于使用 setter 方法进行属性注入的单例 Bean,Spring 可以利用三级缓存机制来解决循环依赖问题。其核心原理是将 Bean 的实例化和初始化过程分离,在实例化后将 Bean 提前曝光到缓存中,当其他 Bean 依赖该 Bean 时,可以从缓存中获取到未完全初始化的 Bean 实例进行注入。
  • 原型(prototype)scope 的循环依赖:原型 Bean 每次请求都会创建一个新的实例。由于每次创建都是新的对象,Spring 无法像处理单例 Bean 那样利用缓存来解决循环依赖问题。因此,对于原型 Bean 的循环依赖,Spring 不会进行处理,需要开发者自己解决。

Spring 真正创建 Bean 对象的核心类及过程

Spring 创建 Bean 对象的最核心方法为 AbstractAutowireCapableBeanFactory#doCreateBean,在这个方法中,会依次完成 Bean 对象实例化、属性注入、调用初始化方法进行一些初始化操作。

  1. createBeanInstance 方法

    此方法的核心任务是实例化 Bean 对象,其本质是调用对象的构造方法来创建对象实例。在 Spring 框架里,它会依据 Bean 的定义信息,选择合适的构造函数来创建对象。这可能涉及到无参构造函数、有参构造函数的选择,甚至可能使用工厂方法来创建对象。

  2. populateBean 方法

    该方法的主要作用是对 Bean 的依赖属性进行注入,常见的如使用 @Autowired 注解进行自动注入。在这个阶段,Spring 会查找 Bean 所依赖的其他 Bean,并将这些依赖的 Bean 注入到当前 Bean 中。

  3. initializeBean 方法

    此方法主要用于调用 Bean 的初始化方法,例如实现了 InitializingBean 接口的 afterPropertiesSet 方法,或者在 Bean 定义中指定的 initMethod 方法。这些方法通常用于在 Bean 的属性注入完成后,进行一些初始化操作。

Spring 解决循环依赖的前提条件

  • 不全是构造器方式的循环依赖:如果所有的循环依赖都是通过构造器注入实现的,Spring 无法打破循环依赖的死循环,因此必须至少有一部分依赖是通过 setter 方法或其他非构造器方式注入的。
  • 必须是单例:Spring 的三级缓存机制是基于单例 Bean 的特性实现的,只有单例 Bean 才能保证在整个应用程序的生命周期中只有一个实例,并且可以被缓存和复用。对于原型 Bean,每次请求都会创建新的实例,无法使用缓存来解决循环依赖问题。

三级缓存的作用

在 Spring 中,三级缓存主要用于解决单例 Bean 的循环依赖问题。循环依赖指的是两个或多个 Bean 之间相互依赖,形成一个闭环。例如,Bean A 依赖 Bean B,而 Bean B 又依赖 Bean A。Spring 使用三级缓存来巧妙地处理这种情况,确保单例 Bean 能够正确创建。

注意

  1. 三级缓存只能解决 setter 注入的循环依赖,无法解决构造器注入的循环依赖;
  2. 原型(prototype)作用域的 bean 无法解决循环依赖;
  3. 如果 Bean 有 AOP 代理,三级缓存中的 ObjectFactory 会返回代理对象;

getBean(AbstractBeanFactory#getBean(java.lang.String))源码看调用时序图:

1. getBean(A)  // AbstractBeanFactory-> doGetBean(A)-> getSingleton(A) [一级缓存没有]  // DefaultSingletonBeanRegistry-> createBean(A)   // AbstractAutowireCapableBeanFactory-> doCreateBean(A)-> 实例化A-> addSingletonFactory(A) [A加入三级缓存]  -> populateBean(A) [填充属性]-> getBean(B) [发现依赖B]-> doGetBean(B)-> getSingleton(B) [一级缓存没有]-> createBean(B)-> doCreateBean(B)-> 实例化B-> addSingletonFactory(B) [B加入三级缓存]-> populateBean(B) [填充属性]-> getBean(A) [发现依赖A]
http://www.dtcms.com/a/483027.html

相关文章:

  • 怎么样看网站用什么程序做的开发公司经营范围
  • 小广告网站音乐网站系统怎么做
  • 单片机中的TVS管
  • c++最常用的几种设计模式
  • 河南平台网站建设公司临沂企业自助建站系统
  • 下载 asp 网站源码响应式网站 翻译代码
  • 大气医院网站源码河北省住房和城乡建设厅信用网站
  • 【agent】AI 数字人构建10:FunASR 1:语音识别C++服务/客户端构建
  • 教育机构网站建设方案书企业邮箱注册需要多少钱
  • 河南省建设工程监理协会网站cms 导航网站
  • Centos Stream 8 Tomcat学习
  • 网站系统cmsphp教育网站开发工作
  • 在Ubuntu22.04和24.04中安装Docker并安装和配置Java、Mysql、Tomcat
  • 【Linux】线程同步与互斥(1)
  • 网站开发英语英语义乌网八方资源家1688网商网
  • 基于单片机的PID调节脉动真空灭菌器上位机远程监控设计
  • 汕头网站关键词优化教程资源分享网站怎么做
  • STM32H7xx 运行 LWIP 时的 MPU 配置介绍 LAT1510
  • 能动框架战场:如何摆脱供应商锁定并在下次AI战争中生存
  • 免费试用网站空间人人开发接单官网
  • 视联网技术产业观察与分析:视频隐私与安全防护
  • 南通网站建设祥云深圳罗湖网站设计公司
  • 基于蚁群算法优化BP神经网络的实现方法
  • 《Effective Java》第10条:覆盖 equals 时请遵守通用规定
  • 广东广州快速网站制作平台鄂州网站建设哪家好
  • 安卓android自动化测试-uiautomator/uiautomator2
  • 天津 网站设计公司门户网站制作定做
  • React组件复用导致的闪烁问题及通用解决方案
  • Java EE开发技术(Servlet整合JDBC银行管理系统-上)
  • 深入理解string底层:手写高效字符串类