Spring循环依赖底层原理与设计思想
1. 什么是循环依赖?
2. 循环依赖并不能彻底解决,就算非构造方法注入也不能,为什么?
3. “二级缓存”如何解决循环依赖?
4. Spring为什么用“三级缓存”去解决循环依赖?
5. 总结“三级缓存”的精妙之处
bean的生命周期
AService 的生命周期
1实例化(new Aservice)---->原始对象---->三级缓存map<beanName,lamda表达式(beanName,bd,原始对象)>
2填充bService属性 ---->单例池中去找对应的bean对象---->创建bService对应的Bean
3填充其他属性
4正常情况AOP的地方:AOP ----->AService的代理对象
4.1 earlySingletonObjects<beanName,代理对象>
5放入单例池
wrapIfNecessary 是否需要aop
BService 的生命周期
1实例化(new BService )
2填充bService属性 ---->单例池中去找对应的bean对象--->没有--->循环依赖---->二级缓存---》没有----》三级缓存----》lamda----》执行---->AService的代理对象---》二级缓存----》移除三级缓存中的lamda表达式
3填充其他属性
4正常情况AOP的地方:AOP ----->AService的代理对象
5放入单例池
单例池:第一级缓存,Map<beanName,对象> ConcurrentHashMap
第二级缓存: earlySingletonObjects HashMap 半成品(属性没设置值),是aop后的代理对象
第三级缓存:singletonFactories HashMap
存放lamda表达式的时候不执行lamda表达式,再次获取的时候才会执行。
第三级缓存才是解决循环依赖的关键
使用三级缓存的原因:
aop
不能解决的循环依赖
1两个原型bean互相依赖
2构造方法的互相依赖
这个时候可以在构造方法上增加@Lazy注解,这个时候,构造方法的参数时代理对象