当前位置: 首页 > 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.lryc.cn/news/615754.html

相关文章:

  • 【C++/STL】list模拟实现和迭代器失效问题
  • 基于 RabbitMQ 死信队列+TTL 实现延迟消息+延迟插件基本使用
  • 十、Linux Shell脚本:流程控制语句
  • [Julia] LinearAlgebra.jl 自带包
  • LeetCode 刷题【37. 解数独】
  • LabVIEW 机器人避障控制
  • 企业架构之导论(1)
  • C++设计模式单例模式(饿汉、懒汉模式)
  • Linux操作系统从入门到实战(十六)冯诺依曼体系结构,操作系统与系统调用和库函数概念
  • 【软件测试】BUG篇 — 详解
  • AI测试助手如何让Bug无处可藏
  • uni-app 网络请求终极选型:uni.request、axios、uni-network、alova 谁才是你的真命请求库?
  • Eclipse JSP/Servlet:深入解析与最佳实践
  • 繁花深处:花店建设的时代意义与多元应用—仙盟创梦IDE
  • 计算机视觉全景指南:从OpenCV预处理到YOLOv8实战,解锁多模态AI时代(第五章)
  • 【Docker进阶实战】从多容器编排到集群部署
  • [Linux]学习笔记系列 -- [arm][lib]
  • 13. 是否可以在static环境中访问非static变量
  • 如何在 Ubuntu 24.04 LTS Linux 上安装 MySQL 服务器
  • opencv颜色识别项目:识别水果
  • jmeter常规压测【读取csv文件】
  • Ubuntu 22.04 离线环境下完整安装 Anaconda、CUDA 12.1、NVIDIA 驱动及 cuDNN 8.9.3 教程
  • AI绘画:生成唐初秦叔宝全身像提示词
  • 安全运维工具链全解析
  • ELK分布式日志采集系统
  • 【系统分析师】软件需求工程——第11章学习笔记(上)
  • 旅行者1号无线电工作频段
  • 《解锁 C++ 起源与核心:命名空间用法 + 版本演进全知道》
  • 计算机网络:求地址块128.14.35.7/20中的相关信息
  • 《从零构建大语言模型》学习笔记4,注意力机制1