阿里大佬深度理解总结:Spring的3级缓存和循环引用

供稿:hz-xin.com     日期:2025-01-09
本文旨在深入解析Spring的三级缓存机制以及循环引用问题,旨在为开发者提供对Spring框架中复杂缓存机制的全面理解,避免在实际开发中因对循环引用机制理解不深导致的错误处理。

一、循环依赖现象解析

在编写代码时,经常使用@Autowired注解实现依赖注入。然而,在某些情况下,会发生循环依赖问题,即两个或多个类相互依赖,形成循环引用。通常情况下,这类问题会导致代码运行异常,但有时我们发现代码并未报错,这主要与Spring的缓存机制有关。

二、前置知识

1. 循环依赖的类型:主要考虑的是单例模式下@Autowire引发的循环依赖,不涉及构造器注入或原型作用域的Bean注入。

2. 代理对象的创建时机:在通常情况下,代理对象的创建发生在bean初始化完成后的BeanPostProcessor#postProcessAfterInitialization方法中。然而,在循环依赖情况下,为解决代理对象创建问题,需提前在getEarlyBeanReference中创建代理对象。

3. 三级缓存内容:在Spring中,ObjectFactory#getObject()方法每次调用时,根据是否存在代理等情况决定返回新对象还是旧对象。

4. 从缓存获取对象:通过DefaultSingletonBeanRegistry类的getSingleton方法实现。

三、深入理解

1. 单独使用singletonObjects和earlySingletonObjects可能无法解决循环依赖问题。因为这些缓存中的代理对象是在完成属性填充后的步骤中创建的,而循环依赖场景下,需要在bean初始化前创建代理对象。

2. 单独使用singletonObjects和singletonFactories也难以实现循环依赖的解决,因为缓存机制和代理创建的时机不匹配。

3. 三级缓存如何实现:

1. 解决代理问题:通过在第三级缓存中提前创建代理对象,利用getEarlyBeanReference方法返回代理bean。

2. 解决单例问题:对象在三级缓存中生成后,放入二级缓存中进行缓存,并从三级缓存中移除,以确保单例对象的一致性。

四、总结

Spring的缓存机制分为三级:一级缓存singletonObjects存放可使用的单例;二级缓存earlySingletonObjects存放半成品Bean,尚未完成初始化;三级缓存singletonFactories用于创建对象,然后放入二级缓存,并在对象创建时返回代理对象。通过三级缓存的合理划分,不仅解决了循环依赖问题,还提高了代码的清晰度和逻辑性。

在实际开发中,面对循环依赖问题,开发者应充分理解Spring的缓存机制及其内部工作流程,以便在遇到类似问题时,能正确处理并优化代码结构,提高程序的健壮性和可维护性。

阿里大佬深度理解总结:Spring的3级缓存和循环引用
3. 三级缓存内容:在Spring中,ObjectFactory#getObject()方法每次调用时,根据是否存在代理等情况决定返回新对象还是旧对象。4. 从缓存获取对象:通过DefaultSingletonBeanRegistry类的getSingleton方法实现。三、深入理解 1. 单独使用singletonObjects和earlySingletonObjects可能无法解决循环依赖问题。因为这些缓存中...

顶级膜拜!谷歌大佬带你手撕spring 高级源码笔记,征服面试官的首选_百度...
四、Spring IOC 应用 从基础到高级,逐步深入Spring IOC的应用场景,整个过程思路清晰、易于理解,能够快速上手。五、Spring IOC源码深度剖析 学习源码的过程可能会显得枯燥,但对于每一个开发者而言,深入理解源码是提高代码思维、深入掌握框架的最佳途径。六、Spring AOP 应用 掌握Spring AOP的应用能显著提...

剑指offer!年薪300万P9大佬揭秘Spring全家桶手册,刷完入职字节_百度知 ...
SpringCloud微服务架构实战派:Spring Cloud 是一系列框架的集合,利用 Spring Boot 提供的便利性简化了分布式系统基础设施的开发。本书讲解了 Docker、Consul、Spring Cloud Gateway、Nacos、Sentinel、微服务安全框架和 DevOps 实践工具。SpringMVC学习指南:Spring MVC 是一个基于请求响应的 MVC 框架,具有轻...

膜拜!这真的详细了!阿里大佬汇总整理的MyBatis从入门到精通
深入理解MyBatis:从入门到精通的全面指南MyBatis,源于2001年的iBATIS,最初为密码软件开发服务,2004年由Clinton-Begin捐赠给Apache基金会,历经变迁,2010年改名并独立发展。作为一款强大的持久层框架,它支持自定义SQL查询和高级映射,消除了大量JDBC代码的繁琐,提供XML或注解配置选项。MyBatis的核心在于其...

深度理解Spring AOP:面向切面编程的精髓与应用
理解Spring AOP核心概念:定义业务接口和实现、切面类、切入点和通知。例如,定义切面类包含前置通知,匹配目标类方法。通过Spring配置启用AOP代理,实现增强逻辑在连接点的应用。以方法调用为例,展示前置通知、后置通知和环绕通知的应用。将横切关注点与业务逻辑分离,提高代码灵活性和可维护性。定义切面类,...

哪位大佬有 Spring Boot实战,我需要这百度网盘资源,我找不到,求书籍...
https:\/\/pan.baidu.com\/s\/1WXIthp4Ba22AePjkPEEIRA?pwd=1234 本书以Spring应用程序开发为中心,全面讲解如何运用Spring Boot提高效率,使应用程序的开发和管理更加轻松有趣。作者行文亲切流畅,以大量示例讲解了Spring Boot在各类情境中的应用,内容涵盖起步依赖、Spring Boot CLI、Groovy、Grails、...

springboot集成大全(springboot集成camunda)
springboot集成大全(springboot集成camunda)SpringBoot进阶之日志集成(logback)大家好,一直以来我都本着用最通俗的话理解核心的知识点,我认为所有的难点都离不开「基础知识」的铺垫「大佬可以绕过~」如果你是一路

Springboot中强引用&软引用&弱引用&幻象引用(虚引用)的使用详解_百度知 ...
源码如下:(可以看到这里指明了是弱引用级别)总结看完上面的例子,觉得可以模仿下Springboot的ConcurrentReferenceHashMap,对对象进行一个合理的存储,间接地优化jvm,提高垃圾回收的效率。这两个别搞混了:软引用,内存不足时回收;弱引用,在进行垃圾回收时,不管内存足与否,都会被回收。作者:4ye酱 ...

有没有大佬能详细介绍一下,springbootjdkmavenspring
查看springboot依赖的JDK版本,首先访问spring.io官方网站,进入"Projects\\Spring Boot"页面,点击"LEARN"查看主流springboot版本。版本标识有:CURRENT(当前发布版本)、GA(通用正式发布版本)、SNAPSHOT(快照版本)、PRE(预览版本)、M版本(里程碑版本)、Alpha(内部测试版或预览版)、Beta(公开测试版...

spring—AOP与事务
个人理解,事务在Spring中是借助AOP技术来实现的,可以作为AOP中的一个事务切面。spring源码对事务的处理逻辑,自己研究吧!ORM框架中以Mybatis为例,事务处理就是用到了一个类Transaction,部分源码如下可以看出Transaction管理的就是一个connection,而connection我们很清楚是与用户会话挂钩的。