乐趣区

关于程序员:Spring为何需要三级缓存解决循环依赖而不是二级缓存

明天给大家分享一道大厂面试真题,Spring 为何须要三级缓存解决循环依赖,而不是二级缓存?我一共分为五个局部来给大家介绍:

1、什么是循环依赖?

循环依赖就是指循环援用,是两个或多个 Bean 相互之间的持有对方的援用。在代码中,如果将两个或多个 Bean 相互之间持有对方的援用,因为 Spring 中退出了依赖注入机制,也就是主动给属性赋值。Spring 给属性赋值时,将会导致死循环。那么,哪些状况会呈现循环依赖呢?

2、哪些状况会呈现循环依赖?

循环依赖有三种状态:
1、相互依赖,也就是 A 依赖 B,B 又依赖 A,它们之间造成了循环依赖。

2、三者间依赖,也就是 A 依赖 B,B 依赖 C,C 又依赖 A,造成了循环依赖。


3、自我依赖,也是 A 依赖 A 造成了循环依赖本人依赖本人。

3、Spring 如何解决循环依赖问题?

Spring 中设计了三级缓存来解决循环依赖问题,当咱们去调用 getBean() 办法的时候,Spring 会先从一级缓存中去找到指标 Bean,如果发现一级缓存中没有 便会去二级缓存中去找,而如果一、二级缓存中都没有找到,意味着该指标 Bean 还没有实例化。于是,Spring 容器会实例化指标 Bean(PS:刚初始化的 Bean 称为晚期 Bean),而后,将指标 Bean 放入到二级缓存中,同时,加上标记是否存在循环依赖。如果不存在循环依赖便会将指标 Bean 存入到二级缓存,否则,便会标记该 Bean 存在循环依赖,而后将期待下一次轮询赋值,也就是解析 @Autowired 注解。等 @Autowired 注解赋值实现后(PS:实现赋值的 Bean 称为成熟 Bean),会将指标 Bean 存入到一级缓存。

总结一下,Spring 一级缓存中寄存所有的成熟 Bean,二级缓存中寄存所有的晚期 Bean,先取一级缓存,再去二级缓存。

4、为何须要三级缓存,而不是二级缓存?
那么,后面有提到三级缓存,三级缓存的作用是啥呢?来看这样一张图,三级缓存是用来存储代理 Bean,当调用 getBean() 办法时,发现指标 Bean 须要通过代理工厂来创立,此时会将创立好的实例保留到三级缓存,最终也会将赋值好的 Bean 同步到一级缓存中。大家能够私信我或者在评论区留言获取高清大图。

5、Spring 中哪些状况下,不能解决循环依赖问题?

1. 多例 Bean 通过 setter 注入的状况,不能解决循环依赖问题

2. 结构器注入的 Bean 的状况,不能解决循环依赖问题

3. 单例的代理 Bean 通过 Setter 注入的状况,不能解决循环依赖问题

4. 设置了 @DependsOn 的 Bean 的状况,不能解决循环依赖问题

我是被编程耽搁的文艺 Tom,如果大家还有其余疑难,请在评论区留言。如果本次面试对你有帮忙,请动动手指一键三连分享给更多的人。关注我,面试不再难!

往期视频曾经整顿成文档模式,须要的小伙伴点个关注,点击下方名片!

退出移动版