Spring Bean 生命周期与循环依赖详解

Spring Bean 生命周期与循环依赖详解

  1. Java 对象与 Spring Bean 的区别:

    • Java 对象的创建步骤:编译源码 -> 类加载到 JVM -> 初始化对象。
    • Spring Bean 使用 BeanDefinition 描述对象信息,如 @Scope@Lazy 等。
  2. Spring Bean 生命周期:

    • 扫描 Bean 信息:从 XML、注解或 JavaConfig 中读取。
    • 封装 BeanDefinition :存储到 beanDefinitionMap 中。
    • 执行 BeanFactoryPostProcessor :如 PropertyPlaceholderConfigurer 注入占位符信息。
    • 实例化 Bean:通过反射选择构造器,实例化对象,但未注入属性。
    • 属性注入 :解决依赖,如 UserService 依赖 SendService
    • 初始化工作
      • 检查是否实现了 Aware 接口,如 ApplicationContextAware 获取 ApplicationContext
      • 执行 BeanPostProcessor,如 AOP 关键的 AnnotationAwareAspectJAutoProxyCreator
      • 执行 @PostConstructInitializingBeaninit-method 等初始化方法。
    • 销毁 Bean :执行 destroy-method
  3. 循环依赖解决方案:

    • 三级缓存

      • 一级缓存singletonObjects,存储完全初始化的单例 Bean。
      • 二级缓存earlySingletonObjects,存储未完全初始化的单例 Bean。
      • 三级缓存singletonFactories,存储 Bean 工厂处理代理对象。
    • 过程

      1. 实例化 A:A 放入三级缓存。
      2. 注入 A 的属性:需要 B,实例化 B。
      3. 实例化 B:B 依赖 A,从三级缓存获取 A 的代理,将A代理对象放入二级缓存。
      4. 初始化 B:从二级缓存移至一级缓存。
      5. 返回 A:继续注入 A 的属性,完成初始化,移至一级缓存。
  4. 关键源码位置

    • AbstractApplicationContext#refresh
    • AbstractApplicationContext#finishBeanFactoryInitialization
    • ConfigurableListableBeanFactory#preInstantiateSingletons
    • AbstractBeanFactory#getBean
    • AbstractBeanFactory#doGetBean
    • DefaultSingletonBeanRegistry#getSingleton
    • AbstractAutowireCapableBeanFactory#createBean
    • AbstractAutowireCapableBeanFactory#doCreateBean
    • AbstractAutowireCapableBeanFactory#createBeanInstance
    • DefaultSingletonBeanRegistry#addSingletonFactory
    • AbstractAutowireCapableBeanFactory#populateBean
    • AbstractAutowireCapableBeanFactory#initializeBean

总结:

  • Spring 使用 BeanDefinition 管理 Bean 的元数据。
  • Bean 实例化和属性注入分开进行。
  • 生命周期中提供了多种扩展点,如 BeanFactoryPostProcessor、Aware 接口、BeanPostProcessor 和初始化方法。
  • 三级缓存解决循环依赖问题,通过 ObjectFactory 处理代理对象。
相关推荐
kimble_xia@oracle4 分钟前
SQL 笔记
java·数据库·oracle
David爱编程18 分钟前
深度解析:synchronized 性能演进史,从 JDK1.6 到 JDK17
java·后端
脑子慢且灵37 分钟前
【JavaWeb】一个简单的Web浏览服务程序
java·前端·后端·servlet·tomcat·web·javaee
用户298698530141 小时前
如何在 C# 中用表格替换 Word 文档中的文本?
后端
B612 little star king1 小时前
力扣29. 两数相除题解
java·算法·leetcode
野犬寒鸦1 小时前
力扣hot100:环形链表(快慢指针法)(141)
java·数据结构·算法·leetcode·面试·职场和发展
上官浩仁1 小时前
springboot synchronized 本地锁入门与实战
java·spring boot·spring
Gogo8161 小时前
java与node.js对比
java·node.js
SmartJavaAI1 小时前
Java调用Whisper和Vosk语音识别(ASR)模型,实现高效实时语音识别(附源码)
java·人工智能·whisper·语音识别
山东小木1 小时前
JBoltAI需求分析大师:基于SpringBoot的大模型智能需求文档生成解决方案
人工智能·spring boot·后端·需求分析·jboltai·javaai·aigs