Spring是如何解决Bean的循环依赖?
采用三级缓存解决的 就是三个Map ; 关键: 一定要有一个缓存保存它的早期对象作为死循环的出口
- 一级缓存:存储完整的Bean
- 二级缓存: 避免多重循环依赖的情况 重复创建动态代理。
- 三级缓存:
- a. 缓存是函数接口:通过lambda 把方法传进去( 把Bean的实例和Bean名字传进去(aop创建) )
- b. 不会立即调:(如果在实例化后立即调用的话:所有的aop 不管bean是否循环依赖都会在 实例化后创建
proxy, 正常Bean 其实spring还是希望遵循生命周期在初始化创建动态代理, 只能循环依赖才创建) - c. 会在 ABA (第二次getBean(A) 才会去调用三级缓存(如果实现了aop才会创建动态代理,如果没有实现
依然返回的Bean的实例)) - d. 放入二级缓存(避免重复创建)
夺命连环问:
-
二级缓存能不能解决循环依赖?
- a. 如果只是死循环的问题: 一级缓存就可以解决 :无法避免在并发下获取不完整的Bean?
- b. 二级缓存也可以解决循环依赖: 只不过如果出现重复循环依赖 会多次创建aop的动态代理
-
Spring有没有解决多例Bean的循环依赖?
- a. 多例不会使用缓存进行存储(多例Bean每次使用都需要重新创建)
- b. 不缓存早期对象就无法解决循环
-
Spring有没有解决构造函数参数Bean的循环依赖?
- a. 构造函数的循环依赖也是会报错
- b. 可以通过人工进行解决:@Lazy
i. 就不会立即创建依赖的bean了
ii. 而是等到用到才通过动态代理进行创建