容器是怎么管理 Bean 的?

文章目录

Spring 容器对 Bean 的管理不仅仅是"创建对象"那么简单,它实际上是一套极其严密的生命周期流水线

容器通过 BeanFactory (生产工厂)和 BeanDefinition(施工蓝图)这两个核心组件,完成了从读取配置到销毁对象的所有工作。


1. 核心蓝图:BeanDefinition

在容器真正 new 一个对象之前,它首先要把你的配置(XML、注解、Starter)转化成一个统一的内部结构:BeanDefinition

这个蓝图记录了:

  • Bean 的全类名(Class Name)。
  • 作用域(Scope):单例还是多例。
  • 是否懒加载(Lazy-init)。
  • 依赖关系:它需要注入哪些别的 Bean。
  • 初始化和销毁方法名。

2. 核心管理流程:生命周期流水线

你可以把容器想象成一个自动化工厂,每一个 Bean 都要走完以下流程:

第一阶段:准备与实例化

  1. 加载配置:容器启动,读取扫描路径下的所有类。
  2. 注册 BeanDefinition :将信息存入 BeanDefinitionMap
  3. 实例化(Instantiation):通过反射机制,调用构造函数创建一个"原生对象"。此时它只是个空的 Java 对象,还没注入数据。

第二阶段:装配与填充

  1. 属性赋值(Populate) :容器根据蓝图,把对应的配置参数和依赖的其他 Bean 注入进去(比如 @Value@Autowired)。
  2. Aware 回调 :如果 Bean 实现了 BeanNameAwareApplicationContextAware,容器会把 Bean 的名字或容器引用塞给它。

第三阶段:初始化(Initialization)

  1. BeanPostProcessor 前置处理 :执行所有拦截器的 postProcessBeforeInitialization 方法。
  2. 初始化方法 :先后执行 @PostConstructInitializingBean 接口方法、以及自定义的 init-method
  3. BeanPostProcessor 后置处理 :执行 postProcessAfterInitialization注意:AOP(动态代理)通常就在这一步发生。

第四阶段:生存与销毁

  1. 就绪:Bean 进入单例池(Singleton Objects Map),等待被业务代码调用。
  2. 销毁(Destruction) :当容器关闭时,执行销毁逻辑(@PreDestroy 等)。

3. 核心机制:三级缓存(解决循环依赖)

管理中最难的部分是:如果 A 依赖 B,B 也依赖 A 怎么办?

容器通过三级缓存(本质是三个 Map)来解决这个问题:

  • 一级缓存(singletonObjects):存放完全初始化好的、可以直接用的"成品"Bean。
  • 二级缓存(earlySingletonObjects):存放已经实例化、但还没填充属性的"半成品"Bean。
  • 三级缓存(singletonFactories):存放创建 Bean 的工厂对象,用来处理 AOP 情况下的循环依赖。

逻辑:A 创建时发现依赖 B,先把自己这个"半成品"挂在缓存里,跑去创建 B;B 发现依赖 A,直接从缓存里拿走 A 的"半成品"完成创建,再回头把完整的 B 给 A。


4. BeanFactory vs ApplicationContext

容器的管理能力也分等级:

特性 BeanFactory ApplicationContext
定位 底层接口,提供基本容器功能。 高级容器,继承了前者。
加载时机 懒加载。只有获取 Bean 时才创建。 预加载。容器启动时就创建所有单例。
扩展功能 无。 支持 AOP、国际化、事件广播、资源访问。
应用场景 移动端或资源极度受限环境(现已少用)。 几乎所有 Spring/Spring Boot 应用。

总结

容器管理 Bean 的本质是:利用 BeanDefinition 统一标准,利用"反射 + 缓存"实现自动化组装,利用"生命周期接口"提供可扩展性。

你现在已经看过了 Bean 的创建、销毁、以及容器的管理逻辑。你是否好奇过,为什么 Spring 默认要把 Bean 设计成单例(Singleton),这种设计在处理高并发请求时会有什么潜在的"坑"?

相关推荐
麻瓜生活睁不开眼3 小时前
Android16修改全局桌面视图边框四直角显示为弧边圆角
android·java·深度学习
dear_bi_MyOnly4 小时前
【MyBatis 操作数据库】
java·数据库·学习·mybatis·学习方法
2601_953720824 小时前
【计算机毕业设计】基于Spring Boot的心理健康咨询与评测系统的设计与实现
java·spring boot·后端
丈剑走天涯5 小时前
JDK 17 正式特性
java·开发语言
圣光SG5 小时前
Java操作题练习(七)
java·开发语言·算法
@航空母舰7 小时前
SpringBoot通过Map实现天然的策略模式
java·spring boot·后端
Co_Hui7 小时前
Java 并发编程
java
long3169 小时前
Java 新手入门与实战开发指南
java·开发语言
执笔画流年呀9 小时前
Linux搭建Java项目部署环境
java·linux·运维
程序员天天困9 小时前
Arthas ognl 表达式从入门到实战:掌握在线调试最强的表达式引擎
java·jvm·后端