Java Spring循环依赖原理与bean的生命周期图文案例详解
前言
Spring是如何处理循环依赖的,又是怎么做到,互相注入对方的proxy bean而不是raw bean的?现在就分析一下
一、循环依赖是什么
Spring中放入两个Service,分别是C1和C2,然后C1和C2又互为对方的成员变量。这种情况C1和C2就可以说是相互循环依赖了
二、源码图解
1. bean的主要生命周期图解

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

可以看到里面有一个很重要的逻辑:
当一个bean经过所有的步骤之后,会去三个缓存里的二级缓存根据beanName获取对象。
- 如果拿不到,就直接使用initializeBean方法之后生成的bean,然后放入到spring容器中
- 如果拿得到,就要对比执行initializeBean前后的bean,如果bean相同,就用二级缓存里的对象作为bean放入到spring容器中,否则就报错
- 所以spring3个缓存中,二级缓存存在的意义就是判断该bean是否被循环依赖过,只有被循环依赖了,注入到其他bean的属性里了,才会放入到二级缓存。
- 然后最后的判断,判断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的生命周期内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
java通过URLClassLoader类加载器加载外部jar代码示例
ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见,下面这篇文章主要给大家介绍了关于java通过URLClassLoader类加载器加载外部jar的相关资料,需要的朋友可以参考下2024-01-01
java并发编程专题(十一)----(JUC原子类)数组类型详解
这篇文章主要介绍了JAVA JUC原子类 数组类型详解的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下2020-07-07
java ThreadPoolExecutor线程池拒绝策略避坑
这篇文章主要为大家介绍了java ThreadPoolExecutor拒绝策略避坑踩坑示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-07-07
SpringBoot基于Disruptor实现高效的消息队列
Disruptor是一个开源的Java框架,它被设计用于在生产者-消费者问题上获得尽量高的吞吐量和尽量低的延迟,本文主要介绍了SpringBoot基于Disruptor实现高效的消息队列 ,具有一定的参考价值,感兴趣的可以了解一下2024-02-02
Spring boot 整合 Redisson实现分布式锁并验证功能
这篇文章主要介绍了Spring boot 整合 Redisson实现分布式锁并验证,redisson是官方推荐的分布式锁实现方案,采用redis自身的原子命令和lua脚本来实现,需要的朋友可以参考下2022-05-05
新建Maven工程出现Process Terminated的问题解决
当Maven出现"Process terminated"错误时,这通常是由于配置文件或路径错误导致的,本文主要介绍了新建Maven工程出现Process Terminated的问题解决,感兴趣的可以了解一下2024-04-04


最新评论