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

Spring 循环依赖会出现什么情况? 如何解决?

Spring 循环依赖会出现什么情况? 如何解决?

一、什么是循环依赖?

在Spring项目中我们经常使用 @Autowired或者@Resource去注入Bean,我们称之为依赖。
当多个Bean之间存在互相依赖的关系,并且出现了循环调用时,Spring就会找不到依赖的七点,就会死循环直到抛出异常。
例如:A依赖B,B依赖C,C依赖A,三者必须在依赖的类初始化之后才会初始化自己,从而出现死循环。

二、实战场景

笔者是在使用Spring Security 编写登录和权限验证代码时出现了循环依赖的场景。

三、解决方法

省流: 笔者使用的方法

  1. 使用@Lazy延迟创建对象
  2. 将@Resource替换为@Autowired
  3. 新建一个空Bean,来解决依赖问题: 例如 A依赖B,B依赖A,我们可以新建一个C,然后让A依赖C,B实现C即可将直接依赖转化为间接依赖关系 中介方式打破循环链
     
    public interface C {
        void doSomething();
    }
    
    
    public class B implements C {
        @Override
        public void doSomething() {
            
        }
    }
    
    
    public class A {
        private C c;
    
        public A(C c) {
            this.c = c;
        }
    
        public void doSomething() {
            c.doSomething();
        }
    }

四、扩展:@Autowired是如何解决循环依赖的的问题的

解决的核心是使用了Spring的三级缓存:

  • 第一级缓存:singletonObjects,用于存放完全初始化好的bean,避免重复创建,单例池
  • 二级缓存:earlySingletonObjects 存放原始的bean对象,尚未填充属性,同时也没有进行完成依赖注入的类 (核心)
  • 三级缓存:singletonFactories 用于存放bean工厂对象中的getObject方法,用于产生原始的bean或者代理对象(如果Bean被AOP切面代理)来放入二级缓存
    首先我们要知道,实例化 ≠ 完全初始化,当Spring容器创建bean时,会从一级缓存中寻找,如果没找到,会搜索二级缓存,如果存在就会把它注入,如果没有会找三级缓存。当bean初始化时,如果发现依赖的类没有完成完全初始化,就会先使用二级缓存中的bean实例,当所有的bean都初始化之后再从一级缓存中获取完全初始化的bean
    而我们使用的@Resource并不存在这种机制,会直接抛出BeanCurrentlyInCreationException
    只用两级缓存可以吗?
    如果没有AOP的情况下只是用一级和三级缓存就能解决,但是涉及到AOP时,必须使用了
    如果发生循环依赖的话,就去 三级缓存 singletonFactories 中拿到三级缓存中存储的 ObjectFactory 并调用它的 getObject() 方法来获取这个循环依赖对象的前期暴露对象(虽然还没初始化完成,但是可以拿到该对象在堆中的存储地址了),并且将这个前期暴露对象放到二级缓存中,这样在循环依赖时,就不会重复初始化了!


http://www.kler.cn/news/334059.html

相关文章:

  • 【JAVA开源】基于Vue和SpringBoot的宠物咖啡馆平台
  • Prompt 初级版:构建高效对话的基础指南
  • git使用“保姆级”教程4——版本回退及分支讲解
  • 数据结构-3.8.栈在括号匹配中的应用
  • 洛谷刷题 P1042 [NOIP2003 普及组] 乒乓球
  • 大模型基础:基本概念、Prompt、RAG、Agent及多模态
  • Spring Boot 控制反转(IoC) 依赖注入(DI)
  • B树系列解析
  • 【数据结构】什么是红黑树(Red Black Tree)?
  • 关键字:volatile
  • 数据库概述(1)
  • easypoi, fastpoi快速导出xlsx,导出多sheet的xlsx
  • mysql-索引笔记
  • 有关自连接表的统一封装
  • 基于定制开发与2+1链动模式的商城小程序搭建策略
  • 招联2025校招内推倒计时
  • 如何在电脑上浏览手机界面
  • 【部署项目】禹神:前端项目部署上线笔记
  • 设计模式-模版方法模式
  • No.4 笔记 | 探索网络安全:揭开Web世界的隐秘防线