Spring 创建bean的流程

ops/2025/3/19 3:37:31/
Bean的创建流程

创建bean流程

Spring 三级缓存
循环依赖的解决流程:

因为成品和半成品对象无法放在都一个map,同时半成品不能暴露出来使用,因此Spring提出三级缓存来解决循环依赖问题

三级缓存定义如下:
/** 一级缓存 单例缓存池 用于保存我们所有的单实例bean */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/** 二级缓存 保存半成品bean实例,当对象需要被AOP切面代时,保存代理bean的实例beanProxy*/
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);/** 三级缓存 存放ObjectFactory,传入的是匿名内部类,ObjectFactory.getObject() 方法最终会调用getEarlyBeanReference()进行处理,返回创建bean实例化的lambda表达式。*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

这里三级缓存value类型ObjectFactory是一个函数式接口,可以传入一个lamda表达式:() -> {return this.getEarlyBeanReference(beanName, mbd, bean)}

循环依赖的源码流程:

入口:AbstarctApplicationContext.refresh()

getEarlyBeanReference方法根据当前bean是否需要代理获取bean对象还是aop代理对象

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {Iterator var5 = this.getBeanPostProcessors().iterator();while(var5.hasNext()) {BeanPostProcessor bp = (BeanPostProcessor)var5.next();if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);}}}return exposedObject;
}

思考:如果只有两个map能不能解决循环依赖?

三级缓存的作用是为了解决spring中Bean依赖注入时发生的循环依赖。如果不需要AOP,那么只需要二级缓存即可实现,如果有AOP,其实二级缓存也能够实现,但是会打破Bean的生命周期,不符合spring的原则,因为需要把AOP对象放入二级缓存中,那么就必须在所有需要AOP处理的Bean对象初始化之前就对Bean对象进行后置处理(生成AOP对象),即使没有发生循环依赖!这并不是spring想看到的,所以spring引入了三级缓存,而且存入的是<beanName, ObjectFactory>结构,ObjectFactory是一个lambda表达式,相当于一个回调函数,当发生循环依赖的时候,会进行lambda表达式的执行,获取到Bean对象或者 AOP代理对象,再将Bean对象或者 AOP代理对象存入二级缓存中,如果之后还有循环依赖指向该对象(类似 A 依赖 B , B 依赖 A和C , C 依赖 A这种情况),就直接从二级缓存里面获取,从而解决了循环依赖。(这里解释了为什么不直接在二级缓存里存放lambda表达式,因为同一个lambda表达式每执行一次,就会生成一个新的代理对象,不能保证单例)

附录


http://www.ppmy.cn/ops/166933.html

相关文章

贪心算法(7)(java) 分发饼干

题目&#xff1a;假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子i&#xff0c;都有一个胃口值g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j&#xff0c;都有一个尺寸 s[j…

鸿蒙路由 HMrouter 配置及使用一

1、学习链接 HMRouter地址 https://gitee.com/hadss/hmrouter/blob/dev/HMRouterLibrary/README.md 2、工程配置 下载安装 ohpm install hadss/hmrouter 添加编译插件配置 在工程目录下的build-profile.json5中&#xff0c;配置useNormalizedOHMUrl属性为true (我这项目创…

基于图神经网络(GNN)的节点分类实战:从GCN到GraphSAGE

图神经网络(GNN)是一种专门用于处理图结构数据的深度学习模型,广泛应用于社交网络分析、推荐系统和生物信息学等领域。图卷积网络(GCN)是GNN的经典方法,而GraphSAGE则通过引入采样机制进一步提升了其性能。本文将通过一个完整的实战案例,展示如何使用GCN和GraphSAGE对图…

【leetcode hot 100 437】路径总和Ⅲ

解法一&#xff1a;&#xff08;深度优先搜索&#xff09;穷举所有的可能 》访问每一个节点 node&#xff0c;检测以 node 为起始节点且向下延深的路径有多少种。递归遍历每一个节点的所有可能的路径&#xff0c;然后将这些路径数目加起来即为返回结果。 /*** Definition for …

人工智能中神经网络是如何进行学习的

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。https://www.captainbed.cn/north 文章目录 引言神经网络的学习过程1. 前向传播2. 计算损失3. 反向传播反向传播的步骤 4. 参数更新5. 重…

基于Python+Django的网上招聘管理系统

项目介绍 PythonDjango网上招聘系统的设计与实现(Pycharm Django Vue Mysql) 平台采用B/S结构&#xff0c;后端采用主流的Python语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。整个平台包括前台和后台两个部分。 - 前台功能包括&#xff1a;首页、岗位详情页、简历中…

解锁 AI 开发的无限可能:邀请您加入 coze-sharp 开源项目

大家好&#xff01;今天我要向大家介绍一个充满潜力的开源项目——coze-sharp&#xff01;这是一个基于 C# 开发的 Coze 客户端&#xff0c;旨在帮助开发者轻松接入 Coze AI 平台&#xff0c;打造智能应用。项目地址在这里&#xff1a;https://github.com/zhulige/coze-sharp&a…

通过Geopandas进行地理空间数据可视化

目录 引言 安装与导入 数据加载与探索 数据预处理 基本地图可视化 添加其他数据到地图上 空间分析与查询 地图叠加与分组 空间缓冲区 交互式地图可视化 实际应用案例 城市规划 环境监测 结论 引言 在数据科学领域,地理空间数据可视化扮演着至关重要的角色。它不…