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

SpringBoot学习日记(三)

IOC控制反转和DI依赖注入

看过主包上篇的内容应该就很好理解这两个Spring特性功能了,现在就再来总结一下,IOC就是从以前我们自己手动new一个Bean变成了由Spring容器管理Bean的生命周期,也就是Bean的生死基本上不用我们管了,而这个DI依赖注入就是把Spring容器管理的Bean的对象的地址引用赋值给需要使用的类的变量中,让这个Bean可复用,这样来看是不是就很简单了。

循环依赖

循环依赖是指两个或多个Bean相互依赖形成的环形引用链,导致容器无法完成依赖注入。

这个应该很好理解吧,就和主包之前JVM系列中引用计数法一样,是一个矛盾的问题,解决的办法也很多,但是Spring在进行Bean的加载的时候使用的就是三级缓存的技术,什么是三级缓存呢?就是把Bean分成三个池子,大池子就是完成好的Bean对象,二级就是半成品的Bean对象,三角呢就是刚刚实例化的Bean对象,他们三个都是map结构,然后我们来说一下他们的区别。

 一级缓存:singletonObjects

  • 存储内容​:完全初始化好的单例Bean
  • 数据结构​:ConcurrentHashMap<String, Object>
  • 特点​:
    • 存储的是成品Bean
    • 所有属性已注入
    • 初始化方法已执行
    • 可以被直接使用

二级缓存:earlySingletonObjects

  • 存储内容​:提前暴露的Bean早期引用
  • 数据结构​:HashMap<String, Object>
  • 特点​:
    • 存储的是半成品Bean
    • 已实例化但未完成属性注入
    • 用于解决循环依赖
    • 可能被AOP代理包装
  • 生命周期​:

    • Bean实例化后放入
    • Bean完全初始化后移除

    三级缓存:singletonFactories

    • 存储内容​:Bean的ObjectFactory
    • 数据结构​:HashMap<String, ObjectFactory<?>>
    • 特点​:
      • 存储的是Bean工厂
      • 可以生成早期引用
      • 支持AOP代理的延迟生成
      • 在第一次解决循环依赖后移除
    • 核心价值​:
      • 解决AOP代理与循环依赖的冲突
      • 延迟代理对象的生成时机

其实从简单层面来讲使用二级缓存就可以解决这个循环依赖的问题了,但是我们Spring是有扩展机制的,还记不记得上一篇说Bean的生命周期的时候,有说到过属性注入后、Aware接口回调后有过BeanPostProcessor方法,这个里面会调用一个InitializingBean方法这个就是扩展Bean的方法,他会检查当前这个Bean是否生成了代理对象,如果有又做了哪些操作也就是AOP。

假如我们使用二级缓存,我们以下面的图为例,A放在二级缓存、然后到B调用A,B从二级缓存拿到了A,然后B放入一级缓存,回到A这个时候调用C,那么A还是个半成品会放到二级缓存中,然而在Map中Key是无法相同存在的,那么C完成后,A怎么知道自己是否执行了AOP呢?就算有那C怎么知道拿那个map呢?所以三件缓存就是为了解决代理的问题的。

这个是大概的一个流程,这个部分可能很绕,然后不理理解的小伙伴建议还是上B站看视频吧,文章没办法这么清楚的表达思路。

总结

本篇主要说了循环依赖的问题和解决循环依赖的办法——三级缓存,AOP与动态代理下一期再说吧,主包周末水一下。

http://www.dtcms.com/a/324535.html

相关文章:

  • P1152 欢乐的跳
  • 从零开始实现Qwen3(MOE架构)
  • C语言基础05——指针
  • Pinia 状态管理库
  • Redis - 使用 Redis HyperLogLog 进行高效基数统计
  • 无人机集群协同三维路径规划,采用梦境优化算法(DOA)实现,Matlab代码
  • strace的常用案例
  • 基于Qt/QML 5.14和YOLOv8的工业异常检测Demo:冲压点智能识别
  • VSCODE+GDB+QEMU调试内核
  • 为 Prometheus 告警规则增加 UI 管理能力
  • 力扣经典算法篇-47-Pow(x, n)(快速幂思路)
  • 每日算法刷题Day60:8.10:leetcode 队列5道题,用时2h
  • Java Stream流详解:从基础语法到实战应用
  • 安装1panel之后如何通过nginx代理访问
  • Linux系统编程Day11 -- 进程属性和常见进程
  • 智慧社区(十一)——Spring Boot 实现 Excel 导出、上传与数据导入全流程详解
  • Langchain调用MCP服务和工具
  • MySQL的逻辑架构和SQL执行的流程:
  • 正确使用SQL Server中的Hint(10)—Hint简介与Hint分类及语法(1)
  • Spring Boot + SSH 客户端:在浏览器中执行远程命令
  • 深入理解 Java 中的线程池:原理、参数与最佳实践
  • 【密码学】8. 密码协议
  • 金融机构在元宇宙中的业务开展与创新路径
  • 【教学类-29-06】20250809灰色门牌号-黏贴版(6层*5间层2间)题目和答案(剪贴卡片)
  • 使用Python调用OpenAI的function calling源码
  • Pytorch深度学习框架实战教程-番外篇02-Pytorch池化层概念定义、工作原理和作用
  • ROS2 QT 多线程功能包设计
  • PHP项目运行
  • (LeetCode 每日一题) 869. 重新排序得到 2 的幂 (哈希表+枚举)
  • Framework开发之Zygote进程2(基于开源的AOSP15)--init.rc在start zygote之后的事情(详细完整版逐行代码走读)