Java Spring循环依赖原理与bean的生命周期图文案例详解

 更新时间:2021年09月02日 08:36:37   作者:liangsheng_g  
这篇文章主要介绍了Spring循环依赖原理与bean的生命周期图文案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

前言

Spring是如何处理循环依赖的,又是怎么做到,互相注入对方的proxy bean而不是raw bean的?现在就分析一下

一、循环依赖是什么

Spring中放入两个Service,分别是C1和C2,然后C1和C2又互为对方的成员变量。这种情况C1和C2就可以说是相互循环依赖了

二、源码图解

1. bean的主要生命周期图解

在这里插入图片描述

上图是一个没有循坏依赖的bean的主要生命周期节点,下图的循坏依赖可以结合该图解一起看

2.循环依赖图解

在这里插入图片描述

可以看到里面有一个很重要的逻辑:

当一个bean经过所有的步骤之后,会去三个缓存里的二级缓存根据beanName获取对象。

  1. 如果拿不到,就直接使用initializeBean方法之后生成的bean,然后放入到spring容器中
  2. 如果拿得到,就要对比执行initializeBean前后的bean,如果bean相同,就用二级缓存里的对象作为bean放入到spring容器中,否则就报错
  3. 所以spring3个缓存中,二级缓存存在的意义就是判断该bean是否被循环依赖过,只有被循环依赖了,注入到其他bean的属性里了,才会放入到二级缓存。
  4. 然后最后的判断,判断initializeBean方法执行前后对象是否一致,其实就是为了判断被循环依赖的bean在注入到其他bean和自己走完bean生命周期的是不是同一个object,如果不是同一个object,那就有问题,要报错。

在这里插入图片描述

可以看到此处第二个参数allEarlyReference,这个参数就是用来区分从3个缓存里取bean的时候是否需要到3级缓存里取对象,此处为false,所以截止到2级为止。

3. 循环依赖处理完成之后

在这里插入图片描述

直接从Spring容器里拿的是c1 proxy或者c2 proxy,但是其实在属性注入的时候,都是调用的raw对象的set方法,也就是proxy的target调用的set方法。

总结

循环依赖其实耐下功夫读源码,也没有那么难。下次分享为什么循环依赖的其中一个类添加@Async有可能会导致注入失败而抛异常

到此这篇关于Spring循环依赖原理与bean的生命周期图文案例详解的文章就介绍到这了,更多相关Spring循环依赖原理与bean的生命周期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于Feign实现异步调用

    基于Feign实现异步调用

    近期,需要对之前的接口进行优化,缩短接口的响应时间,但是springcloud中的feign是不支持传递异步化的回调结果的,因此有了以下的解决方案,记录一下,需要的朋友可以参考下
    2021-05-05
  • Mybatis Interceptor线程安全引发的bug问题

    Mybatis Interceptor线程安全引发的bug问题

    这篇文章主要介绍了Mybatis Interceptor线程安全引发的bug问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 一文理清什么是BIO以及如何使用

    一文理清什么是BIO以及如何使用

    这篇文章主要介绍了什么是BIO以及如何使用,BIO英文全名是blockingIO,也叫做阻塞IO,是最容易理解、最容易实现的IO工作方式,本文就来通过一些简单的示例为大家讲讲BIO吧,需要的朋友可以参考下
    2023-10-10
  • Spring中的@Repository注解源码详解

    Spring中的@Repository注解源码详解

    这篇文章主要介绍了Spring中的@Repository注解详解,@Repository注解修饰哪个类,则表明这个类具有对对象进行增删改查的功能,而且@Repository是@Component注解的一个派生品,所以被@Repository注解的类可以自动的被@ComponentScan通过路径扫描给找到,需要的朋友可以参考下
    2023-10-10
  • SpringBoot上传文件到本服务器 目录与jar包同级问题

    SpringBoot上传文件到本服务器 目录与jar包同级问题

    这篇文章主要介绍了SpringBoot上传文件到本服务器 目录与jar包同级问题,需要的朋友可以参考下
    2018-11-11
  • Java Optional解决空指针异常总结(java 8 功能)

    Java Optional解决空指针异常总结(java 8 功能)

    这篇文章主要介绍了Java Optional解决空指针异常总结(java 8 功能),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Java线程阻塞的方法区别详解

    Java线程阻塞的方法区别详解

    这篇文章主要介绍了Java线程阻塞的方法区别详解,线程阻塞是指当一个线程无法继续执行时,它会进入阻塞状态,直到某个条件满足后才能继续执行,线程阻塞可以通过多种方式实现,如等待锁、等待IO操作、等待其他线程的完成等,需要的朋友可以参考下
    2023-10-10
  • Java实现将png格式图片转换成jpg格式图片的方法【测试可用】

    Java实现将png格式图片转换成jpg格式图片的方法【测试可用】

    这篇文章主要介绍了Java实现将png格式图片转换成jpg格式图片的方法,涉及java文件读写及图形创建等相关操作技巧,需要的朋友可以参考下
    2018-03-03
  • 基于MyBatis的简单使用(推荐)

    基于MyBatis的简单使用(推荐)

    下面小编就为大家带来一篇基于MyBatis的简单使用(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 关于Java继承中父类和子类构造函数的问题

    关于Java继承中父类和子类构造函数的问题

    这篇文章主要介绍了关于Java继承中父类和子类构造函数的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10

最新评论