Spring 如何解决循环依赖的问题】的更多相关文章

在关于Spring的面试中,我们经常会被问到一个问题,就是Spring是如何解决循环依赖的问题的. 这个问题算是关于Spring的一个高频面试题,因为如果不刻意研读,相信即使读过源码,面试者也不一定能够一下子思考出个中奥秘. 本文主要针对这个问题,从源码的角度对其实现原理进行讲解. 1  过程演示 关于Spring bean的创建,其本质上还是一个对象的创建,既然是对象,读者朋友一定要明白一点就是,一个完整的对象包含两部分:当前对象实例化和对象属性的实例化. 在Spring中,对象的实例化是通过…
目录 1. 什么是循环依赖? 2. 怎么检测是否存在循环依赖 3. Spring怎么解决循环依赖 本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可以应用在我们实际开发项目中. 什么是循环依赖? 怎么检测循环依赖 Spring怎么解决循环依赖 Spring对于循环依赖无法解决的场景 Spring解决循环依赖的方式我们能够学到什么? 1. 什么是循环依赖? 循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环.比如…
Spring 如何解决循环依赖的问题 https://blog.csdn.net/qq_36381855/article/details/79752689 Spring IOC 容器源码分析 - 循环依赖的解决办法 https://www.imooc.com/article/34150…
写在前面 最近,在看Spring源码,看到Spring解决循环依赖问题的源码时,不得不说,源码写的太烂了.像Spring这种顶级的项目源码,竟然存在着这种xxx的代码.看了几次都有点头大,相信很多小伙伴都会跟我有一样的感受.怎么办呢?还是踏下心来,慢慢啃源码.最终,我将Spring如何解决循环依赖的源码总结成下面的流程图,这样,根据流程图读源码就清晰多了!! 图解Spring循环依赖 Spring解决循环依赖问题的源码写的确实挺烂的,就是一顿 if + else 的嵌套操作.暂时还是不给小伙伴们…
一.什么是循环依赖 多个bean之间相互依赖,形成了一个闭环. 比如:A依赖于B.B依赖于c.c依赖于A 通常来说,如果问spring容器内部如何解决循环依赖, 一定是指默认的单例Bean中,属性互相引用的场景.也就是说,Spring的循环依赖,是Spring容器注入时候出现的问题. 二.Spring如何解决循环依赖 1,Spring中单例Bean的三级缓存 第一级缓存〈也叫单例池)singletonObjects:存放已经经历了完整生命周期的Bean对象 第二级缓存: earlySinglet…
什么是循环依赖 当一个ClassA依赖于ClassB,然后ClassB又反过来依赖ClassA,这就形成了一个循环依赖: ClassA -> ClassB -> ClassA 原创声明 本文发布于掘金号[Happyjava].Happy的掘金地址:https://juejin.im/user/5cc2895df265da03a630ddca,Happy的个人博客:(http://blog.happyjava.cn)[http://blog.happyjava.cn].欢迎转载,但须保留此段声明…
导读 前几天发表的文章SpringBoot多数据源动态切换和SpringBoot整合多数据源的巨坑中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构造器依赖,详情请看上面两篇文章,这里不再详细赘述了.本篇文章将会从源码深入解析Spring是如何解决循环依赖的?为什么不能解决构造器的循环依赖? 什么是循环依赖 简单的说就是A依赖B,B依赖C,C依赖A这样就构成了循环依赖. 循环依赖分为构造器依赖和属性依赖,众所周知的是Spring能够解决属性的循…
介绍 先说一下什么是循环依赖,Spring在初始化A的时候需要注入B,而初始化B的时候需要注入A,在Spring启动后这2个Bean都要被初始化完成 Spring的循环依赖有两种场景 构造器的循环依赖 属性的循环依赖 构造器的循环依赖,可以在构造函数中使用@Lazy注解延迟加载.在注入依赖时,先注入代理对象,当首次使用时再创建对象完成注入 属性的循环依赖主要是通过3个map来解决的 构造器的循环依赖 @Component public class ConstructorA { private C…
Spring bean生命周期 可以简化为以下5步. 1.构建BeanDefinition 2.实例化 Instantiation 3.属性赋值 Populate 4.初始化 Initialization(BeanPostprocessor -> Aware,init) 5.销毁 Destruction Spring 三级缓存作用 一级缓存 /** Cache of singleton objects: bean name to bean instance. */ Map<String, Ob…
https://mp.weixin.qq.com/s/FtbzTMxHgzL0G1R2pSlh-A 通常来说,如果问Spring内部如何解决循环依赖,一定是单默认的单例Bean中,属性互相引用的场景.比如几个Bean之间的互相引用: 甚至自己"循环"依赖自己: 先说明前提:原型(Prototype)的场景是不支持循环依赖的,通常会走到AbstractBeanFactory类中下面的判断,抛出异常. if (isPrototypeCurrentlyInCreation(beanName)…
授人以鱼不如授人以渔,首先声明这篇文章并没有过多的总结和结论,主要内容是教大家如何一步一步自己手动debug调试源码,然后总结spring如何解决的循环依赖,最后,操作很简单,有手就行. 本次调试 是使用@Autowired注入,通过来调试源码看spring如何解决的循环依赖问题. 首先创建一个简单的springBoot项目,引入spring-boot-test包即可.可以使用idea提供的spring官网推荐的快速创建. maven依赖 <dependency> <groupId>…
Spring如何解决的循环依赖,是近两年流行起来的一道Java面试题. 其实笔者本人对这类框架源码题还是持一定的怀疑态度的. 如果笔者作为面试官,可能会问一些诸如"如果注入的属性为null,你会从哪几个方向去排查"这些场景题. 那么既然写了这篇文章,闲话少说,发车看看Spring是如何解决的循环依赖,以及带大家看清循环依赖的本质是什么. 正文 通常来说,如果问Spring内部如何解决循环依赖,一定是单默认的单例Bean中,属性互相引用的场景. 比如几个Bean之间的互相引用: 甚至自己…
一.循环引用: 1. 定义: 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比方CircularityA引用CircularityB,CircularityB引用CircularityC,CircularityC引用CircularityA.形成一个环状引用关系. 2. 代码演示样例: CircularityA public class CircularityA { private CircularityB circularityB; public CircularityA()…
title: 从一部电影史上的趣事了解 Spring 中的循环依赖问题 date: 2021-03-10 updated: 2021-03-10 categories: Spring tags: Spring 前言 今天,我们从电影史上一则有趣的故事来了解 Spring 中的循环依赖问题. 1998 年的某一天,<喜剧之王>和<玻璃樽>两部电影进入了拍摄阶段. 在<喜剧之王>需要成龙友情客串一个替身演员,而<玻璃樽>需要周星驰客串一个被警犬拖着的警察. 那么…
前言 说起Spring中循环依赖的解决办法,相信很多园友们都或多或少的知道一些,但当真的要详细说明的时候,可能又没法一下将它讲清楚.本文就试着尽自己所能,对此做出一个较详细的解读.另,需注意一点,下文中会出现类的实例化跟类的初始化两个短语,为怕园友迷惑,事先声明一下,本文的实例化是指刚执行完构造器将一个对象new出来,但还未填充属性值的状态,而初始化是指完成了属性的依赖注入. 一.先说说Spring解决的循环依赖是什么 Java中的循环依赖分两种,一种是构造器的循环依赖,另一种是属性的循环依赖.…
引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种:构造器参数循环依赖 表示通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyIn CreationException异常表示循环依赖. 如在创建TestA类时,构造器需要TestB类,那将去创建TestB,在创建TestB类时又发现需要TestC类,则又去创建Test…
1.Spring解决循环依赖 什么是循环依赖:比如A引用B,B引用C,C引用A,它们最终形成一个依赖环. 循环依赖有两种 1.构造器循环依赖 构造器注入导致的循环依赖,Spring是无法解决的,只能抛出BeanCurrentlyInCreationException异常.因为构造器注入时的参数需要依赖bean的实例.所以无法解决循环依赖的问题. 如在创建A的实例时,发现依赖B,那将去创建B的实例,又发现依赖C,则又去创建C,最终在创建C的时候发现依赖A,从而形成一个环,没办法创建. Spring…
前面说到对象的创建,那么在创建的过程中Spring是怎么又是如何解决循环依赖的呢.前面提到有个三级缓存.就是利用这个来解决循环依赖.打个比方说实例化A的时候,先将A创建(早期对象)放入一个池子中.这个时候虽然属性没有赋值,但是容器已经能认识这个是A对象,只是属性全是null而已.在populateBean方法中对属性赋值的时候,发现A依赖了B,那么就先去创建B了,又走一遍bean的创建过程(创建B).同样也会把B的早期对象放入缓存中.当B又走到populateBean方法的时候,发现依赖了A,好…
导读 前几天发表的文章SpringBoot多数据源动态切换和SpringBoot整合多数据源的巨坑中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构造器依赖,详情请看上面两篇文章,这里不再详细赘述了.本篇文章将会从源码深入解析Spring是如何解决循环依赖的?为什么不能解决构造器的循环依赖? 什么是循环依赖 简单的说就是A依赖B,B依赖C,C依赖A这样就构成了循环依赖. 循环依赖分为构造器依赖和属性依赖,众所周知的是Spring能够解决属性的循…
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解 曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下 曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean de…
前言 在面试的时候这两年有一个非常高频的关于spring的问题,那就是spring是如何解决循环依赖的.这个问题听着就是轻描淡写的一句话,其实考察的内容还是非常多的,主要还是考察的应聘者有没有研究过spring的源码.但是说实话,spring的源码其实非常复杂的,研究起来并不是个简单的事情,所以我们此篇文章只是为了解释清楚Spring是如何解决循环依赖的这个问题. 什么样的依赖算是循环依赖? 用过Spring框架的人都对依赖注入这个词不陌生,一个Java类A中存在一个属性是类B的一个对象,那么我…
前置知识 只有单例模式下的bean会通过三级缓存提前暴露来解决循环依赖的问题.而非单例的bean每次获取都会重新创建,并不会放入三级缓存,所以多实例的bean循环依赖问题不能解决. 首先需要明白处于各个阶段的bean被放在哪里.在DefaultSingletonBeanRegistry类中 /** 一级缓存,存放经历完整生命周期的bean*/ private final Map<String, Object> singletonObjects = new ConcurrentHashMap&l…
1.由同事抛的一个问题开始 最近项目组的一个同事遇到了一个问题,问我的意见,一下子引起的我的兴趣,因为这个问题我也是第一次遇到.平时自认为对spring循环依赖问题还是比较了解的,直到遇到这个和后面的几个问题后,重新刷新了我的认识. 我们先看看当时出问题的代码片段: @Service publicclass TestService1 { @Autowired private TestService2 testService2; @Async public void test1() { } } @…
前言 相信很多小伙伴在工作中都会遇到循环依赖,不过大多数它是这样显示的: 还会提示这么一句: Requested bean is currently in creation: Is there an unresolvable circular reference? 老铁!这就是发生循环依赖了! 当然这里是一个异常情况. 在我的一篇文章中介绍如何避免 Spring 自调用事务失效,其中网友给建议,说可以在类中注入自身,然后调用,而注入自身的过程也是循环依赖的处理过程. 下面就一起看一看,什么是循环…
前言 在研究 『 Spring 是如何解决循环依赖的 』 的时候,了解到 Spring 是借助三级缓存来解决循环依赖的. 同样在上一节留下了疑问: 循环依赖为什么要使用三级缓存?而不是使用二级缓存? AOP 动态代理对循环依赖的有没有什么影响? 本篇文章也是围绕上面的内容进行展开. 笔记也在不断整理,之前可能会有点杂乱. 循序渐进,看一看什么是循环依赖? 开始先简单回顾一下 Bean 的创建过程,当然小伙伴也可以直接阅读『 单例 Bean 的创建 』这篇文章. 不过考虑到阅读本文前再阅读上一篇文…
Spring如何使用三级缓存解决循环依赖 首先来了解一下什么是循环依赖 @Component public class A { @Autowired B b; } @Component public class B { @Autowired A a; } 在对象A创建过程中,需要注入B,因为容器中没有B,则去创建B,B创建过程中又需要注入A,而A在等待B的创建,B在等待A的创建,导致两者都无法创建成功,无法加入到单例池供用户使用. Spring则通过三级缓存来解决循环依赖的问题,另外如果对象的作…
什么是循环依赖? 就是A对象依赖了B对象,B对象依赖了A对象. 比如: // A依赖了B class A{ public B b; } // B依赖了A class B{ public A a; } 那么循环依赖是个问题吗? 如果不考虑Spring,循环依赖并不是问题,因为对象之间相互依赖是很正常的事情. 比如 A a = new A(); B b = new B(); a.b = b; b.a = a; 这样,A,B就依赖上了. 但是,在Spring中循环依赖就是一个问题了,为什么? 因为,在…
前提知识 1.解决循环依赖的核心依据:实例化和初始化步骤是分开执行的 2.实现方式:三级缓存 3.lambda表达式的延迟执行特性 spring源码执行逻辑 核心方法refresh(), populateBean()填充bean对象,设置属性值; getEarlyBeanReference() 在未完成属性赋值之前,提前暴露代理对象,在赋值的时候才确定真实对象. 1.三个map结构分别存储什么类型的对象? -级缓存:成品对象 级缓存:半成品对象 三级缓存:lambda表达式 2.三个map结构在…
Spring源码-循环依赖源码解读 笔者最近无论是看书还是从网上找资料,都没发现对Spring源码是怎么解决循环依赖这一问题的详解,大家都是解释了Spring解决循环依赖的想法(有的解释也不准确,在<Spring源码深度解析>作者也是看别人的博客说明了一下),没有从源码的角度分析是怎么解决循环依赖的,笔者就把自己看源码的过程写一下. 写这一篇文章算是个引路的,Spring为了程序的健壮性做了大量分析校验,调用的方法繁多复杂,我这篇文章为读者清理出解决循环依赖的流程. Spring中对象可以配置…
什么是循环依赖 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不是循环调用,循环调用是方法之间的环调用.如图3-5所示: 图3-5 循环引用 循环调用是无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出错误. Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢?首先让我们来定义循环引用…