Spring中的循环依赖

一.什么是循环依赖

        循环依赖是指多个实体之间相互依赖形成闭环。因为Spring中的Bean存在一系列的生命周期,所以会出现循环依赖的问题。

例如:BeanA依赖于BeanB,BeanB又依赖于BeanA

public class BeanA {
    BeanB beanB;
}
public class BeanB {
    BeanA beanA;
}

二.Spring中Bean的生命周期

        Bean的生命周期大致分为四个阶段:实例化--属性注入--初始化--销毁

基本流程:

  • 加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象;
  • 将BeanDefinition存储在一个名为beanDefinitionMap的Map<String,BeanDefinition>中;
  • ApplicationContext底层遍历beanDefinitionMap,创建Bean实例对象;
  • 创建好的Bean实例对象,被存储到一个名为singletonObjects的Map<String,Object>中;
  • 当执行applicationContext.getBean(beanName)时,从singletonObjects去匹配Bean实例返回 

Spring的后处理器

        Spring的后处理器是Spring对外开发的重要扩展点,允许我们介入到Bean的整个实例化流程中来,以达到动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用。Spring主要有两种后处理器:

  • BeanFactoryPostProcessor:Bean工厂后处理器,在BeanDefinitionMap填充完毕,Bean实例化之前执行;
  • BeanPostProcessor:Bean后处理器,一般在Bean实例化之后,填充到单例singletonObjects之前执行。

1.BeanFactoryPostProcessor

        BeanFactoryPostProcessor是一个接口规范,实现了该接口的类只要交由Spring容器管理的话,那么Spring就会回调该接口的方法,用于对BeanDefinition注册和修改的功能。

        BeanFactoryPostProcessor有一个子接口

  •         BeanDefinitionRegistryPostProcessor ----  专门用于注册BeanDefinition操作

2.BeanPostProcessor

        Bean被实例化后,到最终缓存到名为singletonObjects单例池之前,中间会经过Bean的初始化过程。

Spring Bean的初始化过程

  • Bean实例的属性填充
  • Aware接口属性注入
  • BeanPostProcessor的before()方法回调
  • InitializingBean接口的初始化方法回调
  • 自定义初始化方法init回调
  • BeanPostProcessor的after()方法回调

三.循环依赖解决方案

        Spring提供了三级缓存存储完整Bean实例 和半成品Bean实例,用于解决循环引用问题。

  • 一级缓存:最终存储单例Bean成品的容器,即实例化和初始化都完成的Bean
  • 二级缓存:早期Bean单例池,缓存半成品对象,且当前对象已经被其他对象引用了
  • 三级缓存:单例Bean的工厂池,缓存半成品对象,对象未被引用,使用时在通过工厂创建Bean

使用三级缓存循环依赖过程:例如有BeanA和BeanB,BeanA依赖于BeanB,BeanB又依赖于BeanA

  • BeanA实例化对象,但尚未初始化,将BeabA存储到三级缓存;
  • BeanA属性注入,需要BeanB,从缓存中获取,没有BeanB;
  • BeanB实例化对象,但尚未初始化,将BeanB存储到到三级缓存;
  • BeanB属性注入,需要BeanA,从三级缓存获取BeanA,BeanA从三级缓存移入二级缓存;
  • BeanB执行其他生命周期过程,最终成为完成Bean,存储到一级缓存,删除二三级缓存;
  • BeanA注入BeanB;
  • BeanA执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值