• 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初始化成功,进而完成自己的初始化

    在这里插入图片描述

  • 相关阅读:
    redis使用zset实现数据库多字段排序的一种方式
    装饰者模式
    汽车OTA
    MySQL约束和事务知识归纳。
    『亚马逊云科技产品测评』活动征文|构建生态农场家禽系统
    cdn与云服务器有什么区别
    在Linux系统安装Kafka
    【LeetCode】1687. 从仓库到码头运输箱子
    《Python 计算机视觉编程》学习笔记(二)
    初识Hadoop两大核心:HDFS和MapReduce
  • 原文地址:https://blog.csdn.net/qq_39004632/article/details/128032580