不知道最近有没有被一道Java面试题刷爆朋友圈,Spring框架的循环依赖如何解决。我收到了不少粉丝的提问,在了解到之后,也去网上查询了一些资料,自己也询问了身边的同事,总结出以下几个方面,今天就和我来看一看吧~

寻常情况下,如果问Spring内部怎么去解决循环的依赖性,一定是单默认的单例Bean中,属性互相引用的场景。假设几个Bean之间的互相引用,甚至循环依赖自己。

根据上面的两个图,我们先说一下循环依赖与原型的场景是不互相支持的,通常会走到AbstractBeanFactory类中下面的判断,然后反馈回异常问题。

if (isPrototypeCurrentlyInCreation(beanName)) {  throw new BeanCurrentlyInCreationException(beanName); } 

原因其实并不难,如果要创建一个新的A就会发现需要注入原型字段B,当创建新的原型字段B时又发现需要新的A。这就很尴尬了,禁止套娃!总不能靠猜去判断先是StackOverflow还是OutOfMemory?这也太难了吧~

所以Spring怕你猜起来困难,就非常贴心的出现了BeanCurrentlyInCreationException。真不愧是我最爱的框架。

在基于在构造器上的循环依赖,这就不必再多说了,官方文档有很明显的指示,想让构造器注入去支持循环依赖?这就不可能了,改代码吧······

那么默认单例的属性注入场景,那么Spring对循环依赖是如何支持的呢?

Spring解决循环依赖

这时候我们就不得不说到Spring的内部了,它内部维护了三个Map,这是什么?就是我们常说的三个缓存级别。这是为了让更好理解,其实并没有官方名字坐实这个三级缓存的概念。不过这不重要,接着看就是了。

在Spring的DefaultSingletonBeanRegistry类中,你就会发现它的上面有三个Map:

1.singletonObjects。这个或许是我们最熟悉的部分了,我们通常叫它:单例池,容器,它其实就是缓存创建完成单例Bean的地方。

2.singletonFactories。用来映射创建Bean的原始工厂。

3.earlySingletonObjects。它用来映射Bean的早期引用,这意思就是Map里的Bean并不完整,与其称之为Bean,倒不说它只是一个Instance.

再往后的两个Map就更像是一个“垫脚石”了,创建Bean时用了一下,用完就清理了。

循环依赖的本质

了解本质之后才能知道如何解决,刚才说了Spring如何处理循环依赖,首先,我们跳出“阅读源码”的思维,举个例子,如果让你实现下面的功能,你会如何去做?

1.将指定的一些类实例为单例

2.类中的字段同样实例为单例

3.必须支持循环依赖

假设类A是存在的,那么

public class A {  private B b;
}  // 类B:
public class B {  private A a;
} 

看到了吗?其实就是让你模仿一下Spring,假设A和B被修饰,而且类之间的字段假设是通过Autowired修饰,然后放到Map里面,经过处理之后再放到Map里面。

其实上述并不是“Spring如何去解决循环依赖”而是循环依赖的基本本质,其实在网上可以搜索到很多例子,完全可以去百度一下看一看,这可以让你不在阅读的泥潭里陷得太深进而忽略了问题本质,如果实在是看不懂,逆推Spring的实现原因效果会好很多。

问题的本质竟然在于two sum?

说到这里有没有觉得似曾相识?好像在什么时候见过似的,没错,和two sum的解题是很相似的。什么?你不知道two sum?two sum是刷题网站leetcode序号为1的题,也就是大多人的算法入门的第一题。经常有梗对于这个two sum,感兴趣的可以去看看。咳咳,跑题了,我们再回来

问题的内容是:先给你规定数组,再给定一个数字。再返回到数组里面允许通过相加得到指定数字的两个索引。我们举个例子,给定nums = [2, 7, 11, 15], target = 9 那么要返回 [0, 1],因为2 + 7 = 9这道题的优解是,一次遍历+HashMap:

class Solution {  public int[] twoSum(int[] nums, int target) {  Map<Integer, Integer> map = new HashMap<>();  for (int i = 0; i < nums.length; i++) { int complement = target - nums[i];  if (map.containsKey(complement)) {  return new int[] { map.get(complement), i };  }              map.put(nums[i], i);  }          throw new IllegalArgumentException("No two sum solution");  }  } 

这个时候就需要先去Map中寻找我们需要的数字,如果没有,那么就将数字先保存到Map里面,再寻找到需要的数字时,一起返回即可。

map 循环_被问到Spring循环依赖怎么解决?秀给面试官看!内附图解相关推荐

  1. spring相互依赖怎么解决_被问到Spring循环依赖怎么解决?秀给面试官看!内附图解...

    不知道最近有没有被一道Java面试题刷爆朋友圈,Spring框架的循环依赖如何解决.我收到了不少粉丝的提问,在了解到之后,也去网上查询了一些资料,自己也询问了身边的同事,总结出以下几个方面,今天就和我 ...

  2. js map 排序_数组方法写给女友的一系列 JS 数组操作(建议收藏 | 内附思维导图)...

    前言 最近和女友,咳咳...(说出来可能会被打s)学习JS数组方法,用几个字形容的话就是听说过,实际使用.遇到的时候就分不清具体方法会得到怎样的结果. 今天我将通过这篇文章好好整理一下关于JS数组的方 ...

  3. 面试阿里被问到JVM,不逼逼赖赖,直接盘给面试官看!!!

    面试阿里被问到JVM,不逼逼赖赖,直接盘给面试官看!!! 概述 JVM体系结构 类加载机制 类加载器 类加载过程 双亲委派机制 全盘负责委托机制 打破双亲委派机制 自定义类加载器实现 JVM运行时数据 ...

  4. 面试必问:Spring循环依赖

    前言 Spring如何解决的循环依赖,是近两年流行起来的一道Java面试题. 其实笔者本人对这类框架源码题还是持一定的怀疑态度的. 如果笔者作为面试官,可能会问一些诸如"如果注入的属性为nu ...

  5. 阿里 mysql 架构_阿里java架构教你怎么用mysql怒怼面试官

    说一下mysql比较宏观的面试,具体咋写sql的这里就不过多举例了.后面我还会给出一个关于mysql面试优化的试题,这里主要说的索引和B+Tree结构,很少提到我们的集群配置优化方案. 1.索引是什么 ...

  6. Spring框架你敢写精通,面试官就敢问@Autowired注解的实现原理

    面试官:Spring框架中的@Autowired注解可以标注在哪些地方? 小小白:@Autowired注解可以被标注在构造函数.属性.setter方法或配置方法上,用于实现依赖自动注入. 面试官:有没 ...

  7. 杭州市下沙区PHP招聘_【杭州下沙】杭州下沙招聘|待遇|面试|怎么样-看准网

    看到这个招聘信息的时候,已经距离报名截止日期只有1天,急吼吼的报了名,又和单位人事确认是可以参与的后,剩下的就是期待笔试了.还好,单位说话算话,不久给信周末去笔试,赶到现场,好多人啊!现在真是职场寒武 ...

  8. 面试必问:Spring循环依赖的三种方式

    作者:学习园 链接:https://blog.csdn.net/u010644448 引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时 ...

  9. spring循环依赖及解决方式_来探究一下Spring 循环依赖的三种方式

    引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种: ...

最新文章

  1. 障碍期权定价 python_[宜配屋]听图阁
  2. pytorch统计矩阵非0的个数_PyTorch常见的12坑
  3. 【 Verilog HDL 】寄存器数据类型(reg)与线网数据类型(wire,tri)
  4. 发生心梗后,家属做些什么才能保证患者获救,降低死亡?
  5. Otsu‘s Thresholding的工作原理
  6. win7计算机上缺少网络协议,win7系统安装ipx协议提示找不到相应的模块的解决方法...
  7. Java 接口编程题练习_JAVA学习日记每天进步一点点之接口再学习和内部类、编程题练习、异常学习...
  8. Atiitt 知识图谱的艺术 艾提拉著 目录 1. 常见知识图谱的处理技术 1 2. 常用的公开知识图谱如DBpedia, Freebase, Yago,Openkg等 2 3. 构建知识图谱的方
  9. FOI2019算法冬令营D1
  10. 前端面试八股文(超详细)
  11. facebook piexl 像素追踪
  12. php 中 normdist,excel中的normdist
  13. 【京东】商品评价采集
  14. php生成推广二维码海报、合成图片demo
  15. 怎么把照片转换成jpg格式?jpg格式图片怎么弄
  16. photoshop使用技巧_如何使用Photoshop创建逼真的漫画
  17. MT6737芯片技术资料集锦下载
  18. 服务器raid1怎么重装系统,win7 raid1重装系统图文教程
  19. Swift 代码添加约束
  20. Mybatis中按照年、季度、月、日、最近七天,查询

热门文章

  1. pat 乙级 1004 成绩排名(C++)
  2. 【渝粤教育】广东开放大学 物权法 形成性考核 (43)
  3. 【渝粤题库】陕西师范大学200781 数据库原理及应用 作业
  4. 武汉科技大学计算机研究生拟录取名单,武汉科技大学2021年硕士研究生拟录取名单公示...
  5. 嵌入式linux图形系统设计,轻量级嵌入式Linux图形系统设计与实现
  6. 【数字信号处理】基于DFT的滤波系列2(含MATLAB代码)
  7. java的选项板_CAD工具选项板的介绍以及新建方法
  8. 双代号网络图节点时间参数_管理和实务都考!快速学会单代号与双代号参数计算...
  9. python 爬虫热搜_Python网络爬虫之爬取微博热搜
  10. java default修饰符_Java基础语法二