springIoc依赖注入循环依赖三级缓存

springIoc的理解,原理和实现

控制反转:

理论思想,原来的对象是由使用者来进行控制,有了spring之后,可以把整个对象交给spring来帮我们进行管理

依赖注入DI:

依赖注入,把对应的属性的值注入到具体的对象中,@autowired,populateBean完成属性的注入

容器

beanFactory,存储对象,使用map结构来存储,在spring中一般存在三级缓存,singletonObjects存放完整的bean对象,整个bean的生命周期,从创建初始化使用到销毁的过程都是容器来管理的

1,一般ioc容器的时候设计到容器的创建过程(beanFactory,DefaultListableBeanFactory)
2,加载解析bean对象,准备要创建的bean对象的定义对象 beanDefinition(xml或者注解的解析过程)
3,beanFactoryPostProcessor的处理,此处是扩展点,PlaceHolder
ConfigurSupport,ConfigurationClassProcessor.
4,BeanPostProcessor的注册功能,方便后续bean对象完成具体的扩展对象。
5,通过反射的方式将BeanDefinition对象实例化成具体的bean对象。
6,bean对象的初始化过程(填充属性,调用aware的子类方法,调用BeanPostProcessor前置处理方法,调用init-method方法,BeanPostProcessor的后置处理方法)

描述一下bean的生命周期

1,实例化bean,反射的方式生成对象
2,填充bean的属性:populateBean(),循环依赖的问题(三级缓存)
3,调用aware接口相关的方法:invokeAwareMethod(完成beanName可以获取容器bean的名称,BeanFactory获取当前bean factory这也可以调用容器的服务,BeanClassLoader对象的属性设置)
4,调用BeanPostProcessor中的前置方法:使用比较多的ApplicationContextPostProcessor设置ApplicationContext,Environment,ResourceLoader,EmbeddValueResolver等对象。
5,调用initmethod方法:invokeInitmethod(),判断是否实现了IntialzingBean接口,如果有,调用afterPropertiesSet方法。
6,调用BeanPostProceessor的后置处理方法:spring的aop就是在此实现的,AbstractAutoProxyCreator注册Destuction相关的回调接口。
7,通过getbean获取完整对象
8.销毁 判断是否实现了DisposableBean接口 destroyMethod方法
请添加图片描述

请添加图片描述

循环依赖

什么是循环依赖:

第一种互相依赖:A 依赖 B,B 又依赖 A,它们之间形成了循环依赖

在这里插入图片描述

第二种三者之间的依赖 A依赖B,B依赖C,C依赖A

在这里插入图片描述

第三种是自我依赖:A依赖A形成了循环依赖

在这里插入图片描述

三级缓存

  1. singletonObjects:缓存某个beanName对应的经过了完整生命周期的bean
  2. earlySingletonObjects:缓存提前拿原始对象进行了AOP之后得到的代理对象,原始对象还没有进行属性注入和后续的BeanPostProcessor等生命周期
  3. singletonFactories:缓存的是一个ObjectFactory,主要用来去生成原始对象进行了AOP之后得到的代理对象,在每个Bean的生成过程中,都会提前暴露一个工厂,这个工厂可能用到,也可能用不到,如果没有出现循环依赖依赖本bean,那么这个工厂无用,本bean按照自己的生命周期执行,执行完后直接把本bean放入singletonObjects中即可,如果出现了循环依赖依赖了本bean,则另外那个bean执行ObjectFactory提交得到一个AOP之后的代理对象(如果有AOP的话,如果无需AOP,则直接得到一个原始对象)。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	/** Cache of singleton objects: bean name to bean instance. */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** Cache of singleton factories: bean name to ObjectFactory. */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** Cache of early singleton objects: bean name to bean instance. */
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
}

能否把一级缓存和二级缓存合并,只保留一个map结构来完成类似的功能?

理论上是可行的,一级缓存和二级缓存的value类型都是Object,都可以用来存放对象,只是对象的状态不同而已,所以当使用一个map的时候,只要给定具体的标识就可以解决这个问题,也就是说设置对象的时候,在value中不再直接存放对象,而是对象加标识位,比如0代表成品,1代表半成品,那么一个map就可以存储成品对象和办成品对象了,但是虽然可以这么干,没人会这么做,代码不优雅,而且每次在进行对象的存或者放的时候都要判断是否是成品对象,比较麻烦,直接用两个map结构解决即可

如果只有一级缓存和二级缓存,能否解决循环依赖的问题?

可以,但是有前提条件:没有aop的配置或者不需要创建代理对象的时候,两个map就可以解决循环依赖的问题

为什么三级缓存可以解决aop下的循环依赖问题?三级缓存到底有什么作用?

1,在同一个容器中,能否出现同名的不同对象?
不能,id是唯一标识

2,在同一个容器中,按照标准的生命周期,先创建了原始对象,后续又创建了代理对象,那时会怎么办?
当创建了代理对象之后,应该要使用代理对象的,但是原始对象已经存在,那么应该将原始对象给覆盖掉。getEarlyBeanReference()方法执行的逻辑是一样的

3,三级缓存到底有什么作用,为什么存在代理对象的时候就要使用三级缓存呢?
在标准的bean的生命周期中,要先创建出原始对象,创建出原始对象之后要使用populateBean方法来完成属性的赋值,此时赋值的对象是原始对象,因为代理对象还没有创建,代理对象的创建步骤是在BeanPostProcessor的后置处理方法中,也就是说已经完成赋值之后代理对象才创建出来,所以会报错(this means that said other beans do not use the final version of the bean),如何解决这个问题呢?

需要将代理对象的创建前置,也就是说在对象赋值的那一刻,要唯一性的确定出到底是原始对象还是代理对象,所以会优先把所有的bean都放到三级缓存中,在需要进行对象赋值的时候,从三级缓存中取出lambda表达式,lambda表达式的执行逻辑就是确定原始对象还是代理对象。如果是原始对象就赋值原始对象,如果是代理对象就赋值代理对象。

Spring中哪些情况下,不能解决循环依赖问题?

1,多例Bean通过setter注入的情况,不能解决循环依赖的问题。
当两个多例Bean相互依赖并且使用 Setter 方法注入时,Spring容器无法解决循环依赖。这是因为在多例模式下,每次请求获取一个新的Bean实例,Spring容器无法在创建Bean之前就确定依赖关系。
2,构造器注入的bean情况,不能解决循环依赖的问题。
循环依赖的产生:循环依赖通常在Bean的创建阶段发生,而构造器注入是在Bean创建之前发生的,因此无法通过构造器注入的方式解决已经发生的循环依赖。
3,设置了@DependsOn的Bean情况,不能解决循环依赖的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/313935.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

矩阵的秩-

一、定义、理解 非零子式的最高阶数。 如何理解&#xff1f;什么叫做非零子式的最高阶数&#xff1f;&#xff1f;&#xff1f; 举个例子&#xff1a;有一个5阶矩阵 首先什么叫子式&#xff1f; 例如2阶子式就是&#xff0c;任取某两行某两列组成的行列式&#xff0c;就叫…

【发票识别】支持pdf、ofd、图片格式的发票

背景 为了能够满足识别各种发票的功能&#xff0c;特地开发了当前发票识别的功能&#xff0c;当前的功能支持pdf、ofd、图片格式的发票识别&#xff0c;使用到的技术包括文本提取匹配、ocr识别和信息提取等相关的技术&#xff0c;用到机器学习和深度学习的相关技术。 体验 体…

论文精读:Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models

Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models Status: Reading Author: Chunrui Han, Haoran Wei, Jianjian Sun, Jinrong Yang, Jinyue Chen, Liang Zhao, Lingyu Kong, Xiangyu Zhang, Zheng Ge Institution: 中国科学院大学, 华中科技大学, 旷…

虚幻UE 材质-材质图层、材质图层混合

学习材质图层和材质图层混合的使用&#xff0c;便于节点扫盲。 文章目录 前言一、材质图层混合二、使用步骤总结 前言 材质混合我们之前用Bridge的插件进行混合过 而此次我们的材质混合使用UE自带的材质图层和材质图层混合来实现 一、材质图层混合 材质图层混合是一种允许将…

Vant4在Vue3.3中如何按需导入组件和样式

前言 最近我在Vue 3.3的项目中对Vant4做按需导入时&#xff0c;尽管按照Vant4的官方指南进行操作&#xff0c;但样式仍然无法正确加载。经过深入研究和多篇文章的比较&#xff0c;我终于找到了在Vue3中如何正确的按需导入Vant 4组件和样式的方法。由于Vue3.3和Vant4相对较新&am…

考古学家 - 华为OD统一考试

OD统一考试 分值: 200分 题解: Java / Python / C++ 题目描述 有一个考古学家发现一个石碑,但是很可惜发现时其已经断成多段。 原地发现N个断口整齐的石碑碎片,为了破解石碑内容,考古学家希望有程序能帮忙计算复原后的石碑文字组合数,你能帮忙吗? 备注: 如果存在石碑…

国产六核CPU商显板,三屏异显,米尔基于全志D9360开发板

芯驰D9-Pro 自主可控、安全可信的高性能商显方案 采用国产CPU&#xff1a;集成了6个ARM Cortex-A551.6GHz 高性能CPU和1个ARM Cortex-R5800MHz&#xff1b; 高性能的高安全HSM安全的处理器&#xff0c;支持TRNG、AES、RSA、SHA、SM2/3/4/9&#xff1b; 它包含100GFLOPS 3D G…

CRLF漏洞靶场记录

搭建 利用 docker 搭建 vulhub 靶场 git clone https://github.com/vulhub/vulhub.git 进入 /vulhub/nginx/insecure-configuration 目录 启动前关闭现有的 8080、8081、8082 端口服务&#xff0c;避免端口占用 docker-compose up -d 进入容器 docker exec -it insecure-…

Spring事务失效场景之类内部方法调用及解决方案

一、背景 在日常开发中&#xff0c;经常有需要使用事务来保证数据一致性的情况。简单点的话直接在方法上面加Transactional注解就可以了。 但这样存在一个问题&#xff0c;在整个业务方法层面加注解会把很多并不需要归入事务的操作也归入到了事务里面&#xff0c;这样会可能会…

uni-app修改头像和个人信息

效果图 代码&#xff08;总&#xff09; <script setup lang"ts"> import { reqMember, reqMemberProfile } from /services/member/member import type { MemberResult, Gender } from /services/member/type import { onLoad } from dcloudio/uni-app impor…

用通俗易懂的方式讲解大模型分布式训练并行技术:序列并行

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此&#xff0c;我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群&a…

杭州中科微 BDS/GNSS 全星座定位导航模块 ATGM332D-5N31使用笔记

一、BDS/GNSS 全星座定位导航模块 ATGM332D-5N31 介绍 ATGM332D-5N 系列模块是 12X16 尺寸的高性能 BDS/GNSS 全星座定位导航模块系列的总称。该系列模块产品都是基于中科微第四代低功耗 GNSS SOC 单芯片—AT6558&#xff0c;支持多种卫星导航系统&#xff0c;包括中国的 BDS&a…

C++:cout 的一些注意事项

有时cout不会将结果立即输出到屏幕&#xff08;也就是缓冲&#xff09;&#xff0c;该情况不会对竞赛测评有影响。 例子如下&#xff1a; ps:用puts立即输出 原因&#xff1a; 解决方法&#xff1a;在每一个cout后跟\n或flush cout << "This will be immediately d…

网络变压器POE的功能

网络变压器&#xff0c;也被称为POE&#xff08;Power over Ethernet&#xff09;&#xff0c;是一种用于在以太网中传输数据和电力的技术。它的主要功能包括&#xff1a; 1. 传输数据&#xff1a;网络变压器可以传输高速的网络数据&#xff0c;如10/100/1000Mbps。 2. 传输电…

数据结构二叉树创建及例题(上)

今天就带领大家来到树的世界,树无论是在考试上还是实际学习方面都是比较重点的,大家在这块知识要花时间搞懂. 文章目录 前言 一、树的二叉链表定义 二、二叉树三种遍历方式(递归方式) 1.先序遍历方式(根左右) 2.中序遍历方式(左根右) 3.后序遍历方式(左右根) 三、二叉树的…

ubuntu nginx安装部署

上传nginx-1.18.0.tar.gz mv nginx-1.18.0.tar.gz /usr/local/ #解压 tar -zxvf nginx-1.18.0.tar.gz #安装 cd nginx-1.18.0 #安装依赖包apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev libssl-dev libxslt1-dev libxml2-dev libgeoip-dev openssl libgd…

Cmake 中的list介绍

这个链接非常好&#xff0c;都有例子。 https://www.jianshu.com/p/89fb01752d6f

在线项目实习分享:股票价格形态聚类与收益分析

01前置课程 数据挖掘基础数据探索数据预处理数据挖掘算法基础Python数据挖掘编程基础Matplotlib可视化Pyecharts绘图 02师傅带练 行业联动与轮动分析 通过分析申银万国行业交易指数的联动与轮动现象&#xff0c;获得有意义的行业轮动关联规则&#xff0c;并在此基础上设计量…

vue3安装 router 路由

安装路由 cnpm i vue-router在src文件夹下创建router/index.ts import {createRouter,createWebHashHistory} from vue-router const routercreateRouter({history:createWebHashHistory(),routes:[{path:"/",name:home,component: () > import(../views/Home/i…

pyside6 捕捉主窗口关闭后,进行释放相关的资源

import sys from PySide6 import QtGui from PySide6.QtWidgets import QWidget,QApplication,QMessageBoxclass Message(QWidget):def __init__(self):# 如果希望窗口内嵌于其他部件&#xff0c;可添加parent参数super(Message, self).__init__()# 调用初始化方法self.initUI(…