2021年江东seo做关键词优化
循环依赖问题
先分析下bean生命周期, 简化版:
1. 扫描, 获取所有的BeanDefinition,存入BeanDefinitionMap
2. 遍历BeanDefinition, 准备创建bean
3. 推断构造方法, 通过反射, 实例化bean对象(原始对象)
4. 属性赋值
5. 初始化前, 初始化
6. 初始化后, 可能AOP
7. 把经过完整生命周期对象放入单例池SingletonObjects
触发循环依赖-场景1:
ABean创建 > A依赖了B > 创建BBean > B依赖了A > 发现ABean正在创建
循环依赖解决思路
利用三级缓存
三级缓存
- singletonObjects:单例池, 缓存的是经过完整生命周期的bean
- earlySingletonObjects:缓存的是未经过完整生命周期的bean. 如果出现了循环依赖, 会提前把未经过完整生命周期的bean放入二级缓存, 如果这个bean有AOP, 放入的是代理对象, 否则放原始对象,都是未经过完整生命周期的bean
- singletonFactories:存的是一个ObjectFactory, 一个lambda表达式.当bean实例化后, 会生成一个lambda表达式,放入三级缓存. 这个lambda可能被执行, 也可能不被执行. 当执行时候, 可以获取原始对象或者代理对象.在bean属性赋值时, 如果发现循环依赖(当前正在创建的bean被属性bean依赖),才会执行lambda表达式拿到一个对象, 放入二级缓存.如果bean需要AOP, lambda表达式返回的是代理对象, 否则返回原始对象.