• Java Spring Bean的生命周期 三级缓存


    Java Spring Bean的生命周期 三级缓存

    SpringBean的生命周期:是从 Bean 实例化之后(即通过反射创建出对象之后),到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。Spring Bean的生命周期大体上分为三个阶段:

    • 实例化阶段:Spring框架会取出BeanDefinition的信息进行判断当前Bean的范围是否是singleton的,是否不是延迟加载的,是否不是FactoryBean等,最终将一个普通的singleton的Bean通过反射进行实例化
    • 初始化阶段:Bean创建之后还仅仅是个"半成品",还需要对Bean实例的属性进行填充、执行一些Aware接口方法、执行BeanPostProcessor方法、执行InitializingBean接口的初始化方法、执行自定义初始化init方法等
    • 存储阶段:经过初始化阶段,Bean就成为了一个完整的Spring Bean,被存储到单例池singletonObjects中去了,即完成了Spring Bean的整个生命周期

    在这里插入图片描述


    Bean的实例化链接:Bean的实例化
    Bean后处理器链接:Bean后处理器


    Bean的初始化阶段

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

    Spring在进行属性注入时,会分为如下几种情况:

    • 注入普通属性,String、int或存储基本类型的集合时,直接通过set方法的反射设置进去;
    • 注入单向对象引用属性时,从容器中getBean获取后通过set方法反射设置进去,如果容器中没有,则先创建被注入对象Bean实例(完成整个生命周期)后,在进行注入操作;
    • 注入双向对象引用属性时,就比较复杂了,涉及了循环引用(循环依赖)问题,下面会详细阐述解决方案。

    Spring循环依赖和三级缓存

    当Object1中需要属性注入Object2,Object2也需要属性注入Object1,将Object1和Object2都交给Spring管理时,Spring初始化Bean过程中,假如先初始化Object1,Spring发现需要依赖注入Object2,就会从singletonObjects中去getBean()尝试获取Object2,此时Object2并没有初始化,所以获取不到,那么Object1的初始化挂起,先进行Object2的初始化,又发现了Object2需要依赖注入Object1,此时Object1初始化挂起,并没有实际初始化结束存储到singletonObjects中,所以又去尝试初始化Object1,这就出现循环依赖闭环注入的问题,如下所示

    在这里插入图片描述

    为了解决循环依赖的问题,Spring提供了三级缓存来存储不同初始化完成度的Bean实例

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

    还是上述的问题,有了三级缓存就能解决,当Object2从三级缓存中获取到了Object1的引用,那么Object2就可以当作Object1初始化成功,进而完成自己的初始化

    在这里插入图片描述

  • 相关阅读:
    java中并发包
    spring源码解析——IOC之自定义标签解析
    青少年软件编程C++二级题库(51-60)
    结构体变量的初始化和引用
    Java基于SpringBoot的社区维修平台
    web端程序访问过慢时如何判断问题
    基于Java+SpringBoot+Thymeleaf+Mysql旅游景区景点售票购票系统系统设计与实现
    JTAG 详解
    C++——虚函数、虚析构函数、纯虚函数、抽象类
    【电源专题】电流源
  • 原文地址:https://blog.csdn.net/qq_39004632/article/details/128032580