Spring IOC循环依赖

  • 什么是循环依赖
  • Spring中Bean实例的创建流程
  • Spring三级缓存
  • ClassA创建流程
  • 思考

什么是循环依赖

ClassA中依赖ClassB
ClassB中依赖ClassA

依赖主要分为两种:引用、成员变量。
依赖注入(依赖)分为两种:构造方法、setter方法。

//订单
public class OrderService {@Autowiredprivate UserService userService;public void saveOrder() {//插入订 单表(需要用户名称,而页面只传递一个用户ID)//调用UserService去查询用户信息}
}//用户
public class UserService {@Autowiredprivate OrderService orderService;public void queryOrders() {//调用OrderService的服务}
}

Spring中Bean实例的创建流程

  • 实例化(new):此处通过反射调用构造器new对象,引处可能会发生循环依赖【构造器循环依赖】。无法通过自动解决,只能修改依赖关系或者改为setter方法依赖。
  • 填充属性:此处通过反射调用成员变量setter方法进行依赖注入,此处可能会发生循环依赖【setter方法循环依赖】。可能通过缓存解决。
  • 初始化:Bean初始化。

Spring三级缓存

源码 级别 描述
singletonObjects 一级缓存 用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用
earlySingletonObjects 二级缓存 存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
singletonFactories 三级缓存 存放 bean 工厂对象,用于解决循环依赖

从缓存中获得bean顺序:

  • 先从一级缓存获得,没有则从二级缓存获得,没有则从三级缓存获得。

ClassA创建流程

  1. 实例化
    如果是单例bean,那么会创建ClassA对象并提前被暴露给三级缓存保存。
    实例化过程中只会bean创建出来,成员变量都是空值。

  2. 填充属性
    因为ClassA中有变量ClassB所以需要给ClassB变量赋值,此处从缓存中获得引用对象(现在缓存只有ClassA对象所以找不到)。
    则实例化ClassB对象并把ClassB添加到三级缓存。
    给ClassB填充ClassA对象,此时缓存中有ClassA对象,ClassB进行初始化。

  3. 初始化
    ClassA进行初始化。

注:每次添加缓存操作:添加二级缓存时先删除三缓存,添加一级缓存时会先删除二、三级缓存。

添加二级缓存代码:

添加一级缓存代码:

此时你会感觉二级缓存作用不大,如果把二级缓存删除仿佛也能正常注入,主要有两方面原因:

  • 三级缓存是bean的工厂,如果没有二级缓存那么每次从三级缓存获得出来的bean是不一样的。
  • 二级缓存存放的bean是未初始化完成状态,属于提前暴露bean。
  • 三级缓存也有提前暴露bean,还要对bean做beanPostProcessor后置处理。

思考

  • 如果一个目标对象被aop动态加上事务增强功能(代理对象)的话,那么spring容器中存储的是目标对象,还是增强之后的对象,还是都存储?
    答案是spring只会存储一个对象,如果目标对象被AOP产生了代理对象,那么存储的就是代理对象。

  • aop针对目标对象产生代理对象,是发生在bean创建的哪个流程呢?
    是发生在Bean初始化的过程中,具体说,是发生在Bean调用初始化方法之后,去进行AOP流程。

Spring IOC循环依赖相关推荐

  1. Spring IOC循环依赖问题

    Spring IOC循环依赖问题 什么是循环依赖 循环依赖其实就是循环引用, 也就是两个或者两个以上的Bean互相持有对方,形成闭环,例如:A依赖B,B依赖C,C又依赖于A. Spring中循环依赖的 ...

  2. Spring IOC循环依赖解决方案分析

    Spring IOC循环依赖解决方案分析 这里Spring主要用了三层缓存来完成对循环依赖的实现. 下面的属性来源于DefaultSingletonBeanRegistry类 /** Cache of ...

  3. 被问麻了,Spring 如何处理循环依赖?

    点击关注公众号,利用碎片时间学习 前言 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题,在前面Bean实例化流程中,对属性注入一文多多少少对循环依赖有过介绍,这篇文章详细讲一下Spr ...

  4. Spring 如何处理循环依赖?

    Spring 如何处理循环依赖? 文章目录 Spring 如何处理循环依赖? 项目环境 1.什么是循环依赖? 2.Spring 如何来处理循环依赖? 2.1 allowCircularReferenc ...

  5. Spring源码剖析-Spring如何处理循环依赖

    前言 你是不是被这个骚气的标题吸引进来的,_ 喜欢我的文章的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题, ...

  6. 图解Spring解决循环依赖

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 来源:juejin.cn/post/684490412216 ...

  7. spring 循环依赖_简单说说 Spring 的循环依赖

    作者 | 田伟然 回首向来萧瑟处,归去,也无风雨也无晴. 杏仁工程师,关注编码和诗词. 前言 本文最耗时间的点就在于想一个好的标题, 既要灿烂夺目,又要光华内敛,事实证明这比砍需求还要难! 由于对象之 ...

  8. Spring当中循环依赖很少有人讲,今天让我们来看看吧

    网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...

  9. Spring当中循环依赖很少有人讲,今天一起来学习!

    网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...

最新文章

  1. mysql大表迁移_MySQL 大表迁移
  2. 每日一皮:无良商家,难怪头发越来越少了!
  3. PMP-【第6章 项目进度管理】-2021-2-11(136页-160页)
  4. Java数三退一问题代码_数三退一问题算法(Java)
  5. 2021牛客多校6 - Hopping Rabbit(矩形取模+扫描线)
  6. 马哥linux高薪中级-DNS
  7. ASP.NET 错误
  8. db2 修改表空间自增长_什么是表?什么是表空间?什么是MySQL的表空间?
  9. JavaScript--如何插入JS
  10. C#中Dictionary的用法及用途(转)
  11. 虚拟机队列实战虚拟化存储设计之LUN Sizing
  12. MySQL编码转换防止SQL注入_防止SQL注入和XSS注入的方法总结
  13. 五十二 温柔一刀(下)
  14. 最全的《落日故人情》经典句子大全
  15. 如何使用aria2及webui-aria2下载百度云资源
  16. 树莓派4B (Raspberry pi 32 bit)安装uv4l驱动,解决opencv无法获取CSI摄像头图像问题
  17. 萧十一郎(程序员版)卷一 风四娘和割鹿刀
  18. overleaf / latex 批量添加参考文献
  19. 太极创客的项目太乐1号的改造
  20. 手机版本考试系统载图

热门文章

  1. c语言联想输入法算法,华为:编程实现联想输入法 输入联想功能是非常实用的一个功能,请编程实现类似功能...
  2. 高德地图Js API的使用
  3. freemodbus源码笔记
  4. fm算法详解_Python实现FM算法解析
  5. 计算卫星高度角和方位角
  6. Java内存之本地内存分析神器: NMT 和 pmap
  7. KNN算法--手写识别
  8. 机架式服务器性能,机架式服务器含义解析?其优势分析?
  9. 利用VMware搭建centos环境
  10. JavaScript6——JavaScript和CSS的交互