spring如何处理bean的循环依赖
假设在spring中bean A依赖bean B,bean B依赖bean A,这种循环依赖的情况通常会使用三级缓存的方式进行处理。
什么是三级缓存
一级缓存:存储的是已经实例化完成的bean实例。
二级缓存:存放在这里的是提前暴露的bean半成品。若Bean需AOP代理(如@Async、@Transactional),三级缓存的ObjectFactory会提前生成代理对象并存入二级缓存,避免重复创建代理。
三级缓存:存放的是bean的ObjectFactory对象,通过ObjectFactory.getObject()可以获取具体的bean实例。
如何进行循环依赖处理
spring会按以下步骤进行处理:
- spring调用构造化方法实例化bean A,同时把A的ObjectFactory存入三级缓存。
- 发现A依赖bean B后,会先在一级缓存查询是否已经有bean B的实例,如果没有会在二级缓存查询,如还是没有会在三级缓存查询B的ObjectFactory。如三级缓存都没有,则bean A会暂停注入属性,先去实例化bean B。
- B实例化后,同样会把ObjectFactory存入三级缓存。
- B在注入属性时发现依赖bean A,此时B同样会从一级缓存到三级缓存依次查询。查询到实例后进行属性注入。
- bean B属性注入完成后,bean A恢复注入流程,从三级缓存中查询对应的ObjectFactory。
循环依赖处理过程如下图所示: