首页 > 其他分享 >Spring三级缓存及循环依赖的解决

Spring三级缓存及循环依赖的解决

时间:2024-03-20 20:35:16浏览次数:27  
标签:缓存 Spring 代理 bean 生命周期 AOP 三级

三级缓存的概念是针对单例bean来说的,原型的bean是每次直接创建新的bean对象,

IoC容器中,同一个bean或者其代理对象只能存在一个,不能同时存在

 

一级缓存

存放完整的bean(实例化和初始化都已完成)

二级缓存

提前曝光的不完整的bean(可能是bean,也可能是bean的AOP代理,未进行初始化) 

作用:防止创建出多个相同的bean(或者AOP代理)

三级缓存

存放ObjectFactory,这是一个Lambda表达式,执行这个表达式会拿到bean或者bean的代理

作用:解决AOP问题,因为这个表达式返回的是bean本身或者AOP代理过的bean

 

 

Spring容器启动,扫描代码,拿到很多需要单例的bean,严格根据字母顺序进行实例化

bean在实例化以后都会把自己的lambda接口放入三级缓存,这个lambda的作用是返回bean本身或者返回bean的代理,这个lambda不一定会被执行,仅在解决循环依赖的时候才会被执行

正常情况下,Spring是根据bean的生命周期来创建bean并放入IoC,但是遇到循环依赖的话,会通过三级缓存、提前曝光、提前进行AOP代理 来解决循环依赖(就不是严格按照bean的生命周期了,因为循环依赖的情况很少)

这里最好回顾一下bean的生命周期

 

根据需要从三级缓存取出来的ObjectFactory执行以后会得到的不完整的(可能是AOP代理)bean会放到二级缓存,并移除在三级缓存中的内容

 

 

 

 

如果没有AOP代理的话,不完整的bean直接放入二级缓存,完整的bean放入一级缓存

 

以下举个循环依赖的初始化例子

这里假设有2个bean,A、B, AB相互依赖

1. Spring容器启动,扫描代码,先找到一个需要变成单例的A

2. bean A的生命周期开始

3. 进行实例化A, 把A放到三级缓存,key是A的name,value是一个lamba(ObjectFactory)

4. 设置属性,发现依赖B,依次从一级、二级、三级缓存去找B,没找到,进入B的生命周期

5. bean B的生命周期开始

6. 进行实例化B, 把B放到三级缓存(同上)

7. 设置属性,发现依赖A,依次从一级、二级、三级缓存去找A,找到了,执行A的lambda得到不完整的bean A(可能是AOP代理),把bean A放入二级缓存,并在三级缓存中移除

8. 执行B的剩余生命周期

9. A继续设置属性B,执行A的剩余生命周期

10. 继续扫描初始化需要的单例

 

 

构造环境:

Test1和Test2这2个bean循环依赖

加上Transaction注解,就会让Spring给这两个bean加上代理

properties里面打开允许循环依赖的开关

 

 

 

当需要设置属性是某个bean的时候就会去调用getSingleton方法,

这个方法是依次从一级缓存、二级缓存、三级缓存中找这个bean

 

 

执行ObjectFactory的getObject就是调用了getEarlyBeanReference,

里面又调用了wrapIfNecessary,得到了bean本身或者bean的代理

 

 

参考

https://blog.csdn.net/mweibiao/article/details/126133411

标签:缓存,Spring,代理,bean,生命周期,AOP,三级
From: https://www.cnblogs.com/huainanyin/p/18085247

相关文章

  • spring使用jdk17运行出现编码问题
    遇到一个比较奇怪的问题。这个问题别人也遇到过。https://blog.csdn.net/gao_chuan_g/article/details/115117712一、情况简介使用jdk17+springboot3.x+spring6.x写一个小应用A,其中有一部分代码是用于生成SM2加密后的字符串,这个字符串会再做一些处理,最终会显示在前端的页面。......
  • Spring boot2.7整合jetcache方法缓存 处理数据发生变化时同步更新缓存 删除缓存操作
    上文Springboot2.7整合jetcache方法缓存我们做了个方法缓存的案例可以将接口内容缓存起来是能大大提高效率的但是我们接口的数据大多来自数据库如果我们调用增删查改它的数据变化了那缓存的内容就会因为没有及时更新变的不准确例如我们这样我们在上面定义了......
  • Spring boot2.7整合jetcache方法缓存
    前面的文章我们讲了springboot整合jetcache做基本字符串数据缓存但是我这里有个这样的逻辑我的domain包下有一个book属性类里面就id和name属性设置了对应的setget函数和一个整体的构造函数packagecom.example.javadom.domain;publicclassboo......
  • 【数据脱敏方案】不使用 AOP + 注解,使用 SpringBoot+YAML 实现
    文章目录引入认识YAML格式规范定义脱敏规则格式脱敏逻辑实现读取YAML配置文件获取脱敏规则通过键路径获取对应字段规则原始优化后对数据进行脱敏处理递归生成字段对应的键路径脱敏测试完整工具类引入在项目中遇到一个需求,需要对交易接口返回结果中的指定字段......
  • 1、【AI技术新纪元:Spring AI解码】Spring AI 应用框架
    SpringAI应用框架SpringAI是面向人工智能工程的应用框架。其目标是将Spring生态系统的设计原则如可移植性和模块化设计应用于AI领域,并推广使用POJOs(PlainOldJavaObjects,简单旧式Java对象)作为应用程序的构建块。特点跨AI提供商的可移植API支持,涵盖聊天、文本到图像......
  • springboot-Swagger
    Swagger简介前后端分离Vue+SpringBoot后端时代:前端只用管理静态页面:html==>后端。。模版引擎JSP=>后端是主力前后端分离后端:后端控制层,服务层,数据访问层【后端团队】前端:前端控制层,视图层【前端团队】Swagger号称世界上最流行的API框架RestfulApi文档在线自动生成......
  • Spring入门案例
    一、下载Spring5jar包官网地址:https://spring.io/版本目录:https://spring.io/projects/spring-framework#learn下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring/二、新建java工程2.1新建项目2.2导入jar包必需的jar包2.2.1新建lib......
  • Springboot笔记-05
    1.Springboot的热部署spring为开发者提供了一个名为spring-boot-devtools的模块来使SpringBoot应用支持热部署,提高开发者的开发效率,无需手动重启SpringBoot应用。在pom文件加入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-b......
  • SpringBoot整合Mybatis(SpringBoot3)
    依赖pom.xml:pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://......
  • spring的IOC
    IOC翻译成中文是"控制反转",不是具体技术,而是实现对象解耦的思想。控制反转的意思是将依赖对象生命周期控制权进行反转,全称应该是控制权反转。之前需要一个对象,常用的方法就是在当前对象中new一个对象,那这样有个比较大的问题在于,耦合,一旦new的那个对象构造方法变动,那么所有使用到......