知识改变命运! java高频面试题-在Spring中,当一个Bean依赖另一个Bean时,如果这两个Bean之间出现了循环依赖,Spring会如何处理呢?_猿份哥-lskyf博客社区

java高频面试题-在Spring中,当一个Bean依赖另一个Bean时,如果这两个Bean之间出现了循环依赖,Spring会如何处理呢?

猿份哥 6月前 ⋅ 748 阅读 ⋅ 2 个赞

Spring 中的循环依赖处理

循环依赖是指两个或多个Bean之间相互依赖,形成了相互引用的关系。在Spring框架中,如果遇到循环依赖,即两个Bean互相持有对方的引用,Spring框架如何处理呢?

循环依赖的问题

当Spring容器必须同时实例化相互依赖的Beans时,由于无法同时调用它们的构造方法完成依赖注入,因此容器无法完成Bean的创建。这将导致死循环或抛出StackOverflowError异常。

早期依赖注入

Spring解决循环依赖问题的核心在于“早期依赖注入”。这一策略涉及到三个关键概念:singletonObjectsearlySingletonObjectssingletonFactories

解决循环依赖的原理流程

  1. 依赖注入: 容器加载Bean时,对所有依赖项进行依赖注入。
  2. 早期引用: 如果Bean的构造器中有对其他Bean的引用,则使用一个"早期引用"暂时代替。
  3. 实例化其余Bean: 容器继续实例化和依赖注入其余Bean,并在处理完所有Bean后,开始解析早期引用。
  4. 查找Singleton缓存: 首先尝试从Singleton缓存中查找Bean,如果找到则返回。
  5. 创建新实例: 缓存中未找到时,尝试使用Bean定义的构造器创建新实例。
  6. 填充依赖项: 如果构造器中有依赖其他Bean,使用早期引用来填充这些依赖项。
  7. 异常处理: 如果无法满足依赖关系,Spring将抛出异常。

提前暴露Bean实例

  • SingletonObjects: 表示已经完全初始化的单例Bean实例对象。
  • EarlySingletonObjects: 表示已创建但未完全初始化的单例Bean实例对象。
  • singletonFactories: 表示Bean工厂对象。

实例化过程

当Spring创建Bean对象时,会检查Bean是否已在缓存中且完整。如果正在创建的Bean处于创建中但已完成实例化与初始化,就返回该对象。

EarlySingletonObjects占位Bean对象

如果Bean有构造函数注入的依赖项,则先创建一个占位Bean对象并提前暴露,待依赖注入完成后再进行初始化。

singletonFactories的作用

在Bean实例化到一定程度后(通常是构造方法执行完成),提前暴露的占位Bean对象被添加到singletonFactories中,从而避免循环依赖。

Spring的提前暴露Bean实例的代码实现

public Object getEarlyBeanReference(String beanName, RootBeanDefinition beanDefinition, Object bean) {
    Object exposedObject = bean;
    // 省略同步块和其他操作
    return exposedObject;
}

当Bean有依赖其他Bean时,此方法将正在创建的Bean添加到earlySingletonObjects中,并返回半成品实例。

protected Object doResolveDependency(
        DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames,
        TypeConverter typeConverter, @Nullable Map<String, Object> cachedResult) throws BeansException {
    // ... 省略代码 ...
    if (earlySingletonExposure) {
        Object earlySingletonReference = getEarlyBeanReference(beanName, bd, bean);
        // ... 省略代码 ...
        return earlySingletonReference;
    }
    // ... 省略代码 ...
}

这个方法在解决Bean依赖时,如果条件允许,则生成半成品Bean实例。否则,正常创建并注入依赖Bean。

通过上述机制,Spring框架能够在所有Bean都实例化完成后,正式开始依赖注入的过程,从而解决循环依赖问题。


全部评论: 0

    我有话说:

    java高频面试-SpringBean的生命周期

    SpringBean的生命周期有如下过程: 1.Bean容器找到配置文件Spring Bean的定义。 2.Bean容器利用Java Reflection API创建一Bean的实例。 3

    我向20k+以上的java高级开发工程师提那些面试问题

    公司需要一位java高级开发工程师,找到我去面试。我回忆一下,记录部分我的提问,如果大家刚兴趣可以给我留言,我视情况看是否继续补充,或者是否提供答案。 1.聊聊您对spring Boot一些见解

    java高频面试-Spring Boot的自动配置是如何工作的,以及它的优点是什么?

    Spring Boot的自动配置是其设计理念的核心之一,它通过约定大于配置的思想,为开发者提供一种零配置的开发体验。以下是对这个问题的详细解答: 自动配置原理: Spring Boot通过

    spring boot面试及答案持续更新

    2019-07-28最新整理的spring boot面试及答案 1.Spring Boot是什么 是摘自官方的一段话 Spring Boot is designed to get you up

    java高频面试-Java如何实现序列化和反序列化?

    一.为什么要序列化? 序列化为数据持久化、远程通信、数据交换和对象复制提供便捷的解决方案。它是不同系统间共享和传递对象的一种常用方法。 几常见原因: 持久化数据: 将对象序列化后存储文件系统

    Java如何返回多

      我有一个方法,需要返回多对象。可是Java只能返回一个值,请问如何才能返回多

    java高频面试-线程池execute跟submit的区别?

    ``谈论线程池,其中的execute和submit是种常用的方法,它们任务提交和执行上有所不同。 线程池 execute 与 submit 方法的区别 1.execute 方法

    ...jar没有主清单属性, spring boot或者spring cloud的maven项目 java -jar test.jar 方式启动报错:...jar没有主清单属性

    1.spring boot或者spring cloud的maven项目老是遇到问题...jar没有主清单属性 2.解决方法:pom.xml添加如下代码 <build> <

    java高频面试-mysql的InnoDB与MyISAM存储引擎有哪些区别 ?

    mysql的InnoDB与MyISAM存储引擎有哪些区别 ? MySQL是一个广泛使用的关系型数据库管理系统,其中InnoDB和MyISAM是种常用的存储引擎。它们功能和性能方面存在着显著的差异

    java高频面试-java类加载需要经历哪些过程?

    本篇文章是基于JDK 8及以上版本的Java类加载过程。 Java类加载过程 Java类加载是Java虚拟机(JVM)执行过程的关键步骤。它涉及Java类的动态加载、链接和初始化。本文,我们将

    如果SpringBoot与SpringCloud老是出各种问题,别急!请看下面的SpringBoot与SpringCloud的版本对应详细版

    1.问题 我们开发微服务的时候因为SpringBoot和SpringCloud兄弟版本没有对应好老是出现各种各样的问题。特别苦逼!别急,往下看!遇到就是缘分,我叫猿份哥! 2.原因

    Spring Boot系列2-全局统一异常处理

    原创: 天空和唯美 天空唯美  点击查看原文 为什么要全局统一异常处理如果系统发生异常,不做统一异常处理,前端给用户展示一大片看不懂的文字。做统一异常处理

    Spring Boot应用或SpringCloud程序设置端口号的几种方式

    前言:springboot项目的每个应用都需要设置端口号,如何设置端口号?主要有以下几种方式 1.通过配置文件设置: (1)/src/main/resources/路径下的

    SpringBoot系列21-实现策略模式

    如何spring boot 使用@component 实现策略模式 1. Spring Boot 实现策略模式可以使用 @Component 注解来将策略类标记为 Spring 的组件,并

    不同品牌的显卡能否同一台电脑上同时运行?

    构建或升级您的计算机,考虑使用不同品牌的显卡以获取最佳性能是一个常见诉求。然而,兼容性可能成为您面的问题之一。 1. 兼容性问题的考量 尝试同一台电脑上同时使用不同品牌的显卡,可能出现

    加入公众号
    加入公众号