深入理解Spring循环依赖解决机制
186 浏览量
更新于2024-09-01
收藏 86KB PDF 举报
"简单了解Spring循环依赖解决过程"
在Spring框架中,循环依赖指的是两个或多个bean之间形成相互依赖的关系,导致它们无法正常初始化。Spring提供了几种机制来处理这种问题,主要集中在属性的循环依赖上,因为构造器的循环依赖在Java中通常是无法解决的,会导致`StackOverflowError`。下面我们将深入探讨Spring如何解决属性循环依赖。
1. **单例bean的三级缓存**
Spring使用三级缓存来处理单例bean的循环依赖问题。这三级缓存分别是:
- `SingletonObjects`: 存储完全初始化好的bean,也就是已经完成了依赖注入的对象。
- `EarlySingletonObjects`: 存储的是早期暴露的bean,此时bean只是实例化了,但还没有完成依赖注入。
- `SingletonFactories`: 存储bean的工厂,可以用来创建bean实例。
2. **实例化过程**
当Spring遇到一个bean的实例化请求时,会按照以下步骤进行:
- **预实例化**: 对于单例bean,Spring会在容器启动时进行预实例化,这样可以尽早发现循环依赖。
- **创建Bean实例**: 使用`DefaultListableBeanFactory`的`createBean()`方法开始实例化过程。
- **填充属性值**:
- **检查早起暴露**: 如果bean已经存在于`EarlySingletonObjects`中,那么它会被直接返回,从而打破循环依赖。
- **如果没有早起暴露**: Spring会创建一个代理,将这个未初始化的bean放入`SingletonFactories`缓存,然后尝试继续实例化其他依赖。
- **依赖注入**: 此时如果遇到了循环依赖,Spring会从`SingletonFactories`中取出对应的bean工厂,使用工厂创建一个代理对象,将这个代理对象注入到依赖者中,从而避免了直接依赖未初始化的bean。
3. **依赖注入阶段**
- **填充属性**: 在依赖注入过程中,Spring使用了` Aware`接口(如`BeanFactoryAware`、`ApplicationContextAware`等)让bean可以感知到容器,从而在必要时获取其他bean。
- **属性注入**: 通过`PropertyPlaceholderConfigurer`、`AutowiredAnnotationBeanPostProcessor`等后处理器完成属性的自动装配。
- **最终初始化**: 所有依赖注入完成后,bean才会被添加到`SingletonObjects`缓存中,成为完全初始化的bean。
4. **原型bean与循环依赖**
对于原型(prototype)作用域的bean,Spring不会尝试解决循环依赖,因为原型bean每次请求都会创建一个新的实例,这样的场景下循环依赖通常不是问题。
5. **注意事项**
- Spring的循环依赖解决方案只适用于单例bean,对于 prototype 或其他作用域的bean,开发者需要自行处理循环依赖问题。
- Spring不支持在构造器中的循环依赖,因为它无法在构造阶段预测和解决依赖关系。
- Spring的循环依赖解决方案依赖于AOP代理,因此如果关闭了AOP,循环依赖可能无法正确处理。
Spring通过其独特的三级缓存机制,以及在bean生命周期的不同阶段进行干预,有效地解决了单例bean的循环依赖问题。然而,设计时应尽量避免循环依赖,以提高代码的可读性和可维护性。
2022-06-15 上传
2022-06-28 上传
2020-08-18 上传
2023-05-19 上传
2023-05-30 上传
2023-05-27 上传
2023-07-27 上传
2023-07-13 上传
weixin_38526979
- 粉丝: 6
- 资源: 964