Spring循环依赖的问题
bean : 被Spring管理的对象
bean的生命周期
1 扫描类:每一个类
2 BeanDefinition : 将扫描的每一个类信息封装入一个BeanDefinition,然后将每一个BeanDefinition放入BeanDefinitionMap (属于BeanFactory类)
3 BeanFactoryPostProcessor : 处理 BeanFactory
4 推断构造函数,根据BeanDefinition来创建原始对象
5 属性注入
6 Aware Init
7 BeanPostProcessor : 对原始对象进行加工
8 将Bean放入SingletonObjects
1 普通循环依赖
A 类
1 扫描类
2 将类信息封装入BeanDefinition
3 创建原始对象 a :将原始对象a,放入二级缓存
4 属性注入 :需要对象b - 开启b对象的Bean生命周期 (最后从单例池中获取 b 对象)
5 Aware Init
6 BeanPostProcessor :
7 将Bean放入SingletonObjects :将 a 对象放入单例池
B 类
1 将类信息封装入BeanDefinition
2 创建原始对象 b :
3 属性注入 : 需要a对象 -从二级缓存中获取a 对象
4 Aware Init
5 BeanPostProcessor :
6 将Bean放入SingletonObjects :将b对象放入单例池
如果有AOP产生,在最后检验B.a == a ,不通过
2 有AOP的循环依赖
A 类
1 扫描类
2 将类信息封装入BeanDefinition
3 创建原始对象 a :将原始对象a传入ObjectFactory(Key)的Lombda表达式(Value)中,将表达式以Key Value 的形式放入SingletonFactories 集合中(三级缓存)
4 属性注入 :需要对象b - 开启b对象的Bean生命周期 (最后从单例池中获取 b 对象)
5 Aware Init
6 BeanPostProcessor :对原始对象进行加工(AOP),如果没有循环依赖,就在此步产生代理对象,否则从二级缓存取出代理对象
7 将Bean放入SingletonObjects :将 a 对象放入单例池
B 类
1 将类信息封装入BeanDefinition
2 创建原始对象 b :
3 属性注入 : 从三级缓存中获取ObjectFactory并执行,获取代理对象并且放入二级缓存,再将ObjectFactory从SingletonFactories 集合中移除,然后从二级缓存获取代理对象
4 Aware Init
5 BeanPostProcessor :对原始对象进行加工
6 将Bean放入SingletonObjects:将b对象放入单例池
有AOP产生,在最后检验B.a == a ,通过
总结
SingletonObjects 单例池: 缓存的是经过完整的生命周期的Bean
earlySingletonObjects 二级缓存 : 如果有AOP,缓存的就是通过原始对象而产生的代理对象,如果没有AOP,缓存的就是原始对象
SingletonFactories 三级缓存:缓存的是ObjectFactory在Bean的生命周期中会提前暴露一个工厂,当没有AOP时会返回一个原始对象,否则返回一个基于原始对象的代理对象