【重难点】【Spring 03】循环依赖一、循环依赖
1.定义2.Bean 的生命周期3.三级缓存4.解决流程 一、循环依赖 1.定义
循环依赖的定义很简单,就是 ServiceA 中注入了 ServiceB,ServiceB 中也注入了 ServiceA,Spring 通过三级缓存解决循环依赖的问题
2.Bean 的生命周期 Spring 扫描有注解的 class 得到 BeanDefinition根据 BeanDefinition 生成 Bean(根据 class 推断构造方法,使用反射构造原始对象)将创建原始对象的 lambda 表达式放入三级缓存中对原始对象进行依赖注入如果原始对象中的方法需要 AOP,那么还需要生成代理对象放入二级缓存中最后把最终生成的对象或者代理对象放入一级缓存中,使用的时候直接从一级缓存中获取 3.三级缓存 一级缓存:singletonObjects二级缓存:earlySingletonObjects三级缓存:singletonFactories三种缓存各自的作用
singletonObjects:存放的是已经经历了完整生命周期的 Bean 对象earlySingletonObjects:存放的是原始 Bean 对象,即未经历完整生命周期的 Bean 对象singletonFactories:存放的是创建原始 Bean 对象的 lambda 表达式,也被称为对象工厂 4.解决流程
创建 ServiceA 的第一阶段
将创建 ServiceA 的 lambda 表达式放到三级缓存中在 ServiceA 的原始对象中注入 ServiceB我们先尝试在一级缓存中获取 ServiceB,发现一级缓存中没有 ServiceB接着去二级缓存中找,发现二级缓存中也没有最后我们在三级缓存中也没有找到,这个时候我们就需要创建 ServiceB创建 ServiceB
将创建 ServiceB 的 lambda 表达式放到三级缓存中在 ServiceB 的原始对象中注入 ServiceA我们先尝试在一级缓存中获取 ServiceA,发现一级缓存中没有接着去二级缓存中找,发现二级缓存中也没有最后我们在三级缓存中找到了,执行 lambda 表达式得到 ServiceA然后将 ServiceA 放入二级缓存中,并且注入到 ServiceB 中执行三级缓存中的 lambda 表达式,获取 ServiceB将 ServiceB 放入一级缓存中ServiceB 创建完成创建 ServiceA 的第二阶段
将创建完成的 ServiceB 注入到 ServiceA 的原始对象中将二级缓存中的 ServiceA 放入一级缓冲中ServiceA 创建完成