面试题:Spring如何解决循环依赖?

简介: 面试题:Spring如何解决循环依赖?

面试题:Spring如何解决循环依赖?

作为面试者,我很乐意分享关于Spring如何解决循环依赖的问题。

Spring框架中,如果两个Bean之间存在相互依赖的关系,并且这种依赖是循环的,则可能会导致无法创建完整的对象图和出现循环依赖异常。为了解决这种类型的问题,Spring使用了两种技术:构造函数参数注入和三级缓存(三级缓存又称“早期对象”的缓存)。

  1. 构造函数参数注入

对于通过构造函数进行自动装配的Bean之间的循环依赖,可以使用构造函数参数注入来解决。Spring容器将创建Bean时所需的全部依赖项注入到构造函数中,并使用代理对象封装正在创建的Bean,从而避免了循环依赖。例如:

public class ProductService {
    private final ProductRepository productRepository;
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }
}
public class ProductRepository {
    private final ProductService productService;
    public ProductRepository(ProductService productService) {
        this.productService = productService;
    }
}

在上述代码中,ProductService依赖于ProductRepository,而ProductRepository又依赖于ProductService。由于它们的依赖关系是循环的,因此可以使用构造函数注入来解决。

  1. 三级缓存技术

当Bean之间的循环依赖问题无法通过构造函数来处理时,Spring使用三级缓存来解决此类问题。在第一阶段,当创建一个Bean对象后,会先判断这个Bean是否已经缓存在singletonObjects这个单例池中了,如果是直接拿出来返回,如果没有就进入到第二阶段。在第二阶段,会将当前正在创建的Bean放入earlySingletonObjects这个早期单例列表中并设置其状态为“正在创建中”,然后继续创建其所依赖的其他Bean。在依赖的其他Bean都创建好后,在开始对当前Bean进行初始化之前,会将早期单例池中所有状态为“正在创建中”的Bean都提前暴露(替换)成代理对象,并更新它们的状态为“已创建”。由此,在对Bean进行初始化的过程中,该Bean从早期单例列表中获取到的代理对象,以满足该Bean对其它Bean的依赖,从而避免了循环依赖异常的发生。

总之,Spring框架可以通过构造函数参数注入与三级缓存技术来处理Bean之间相互依赖、且嵌套或循环的情况,保证依赖关系传递的正确性及完整性,从而符合java设计模式重要的“解耦”思想。

相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
76 2
|
22天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
41 2
|
25天前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
2月前
|
设计模式 缓存 Java
面试题:谈谈Spring用到了哪些设计模式?
面试题:谈谈Spring用到了哪些设计模式?
|
3月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
|
3月前
|
缓存 Java 数据库
【Java面试题汇总】Spring篇(2023版)
IoC、DI、aop、事务、为什么不建议@Transactional、事务传播级别、@Autowired和@Resource注解的区别、BeanFactory和FactoryBean的区别、Bean的作用域,以及默认的作用域、Bean的生命周期、循环依赖、三级缓存、
|
2月前
|
Java 程序员 Spring
Spring事务的1道面试题
每次聊起Spring事务,好像很熟悉,又好像很陌生。本篇通过一道面试题和一些实践,来拆解几个Spring事务的常见坑点。
Spring事务的1道面试题
|
2月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
193 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
3月前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
47 4
|
3月前
|
XML Java 开发者
经典面试---spring IOC容器的核心实现原理
作为一名拥有十年研发经验的工程师,对Spring框架尤其是其IOC(Inversion of Control,控制反转)容器的核心实现原理有着深入的理解。
155 3