服务公告
蓝易云:Spring之BeanFactory
发布时间:2025-12-24 00:15
什么是 BeanFactory:Spring 容器的“最小可用内核” ☑️
在当前 Spring 官方定义里,BeanFactory 是访问 Spring Bean 容器的根接口:它持有一组以名称唯一标识的 BeanDefinition,并按配置返回 单例或 原型实例;在具体应用上下文中还可扩展更多 Scope(例如 Web 的 request/session)。(Home)
它的定位很务实:做“注册 + 创建 + 依赖装配”的底座;至于更企业化的能力(事件、国际化、资源加载等),交给更上层的 ApplicationContext。(Home)

原理解释表:BeanFactory 解决的 4 件关键事
| 关注点 | BeanFactory 在做什么 | 你得到的收益 |
|---|---|---|
| 组件治理 | 统一注册与管理应用组件(Bean)(Home) | 配置集中、依赖关系清晰 |
| 实例策略 | 按 singleton/prototype 等策略返回实例(Home) | 控制内存与生命周期边界 |
| 依赖注入 | Spring 的 DI 能力基于该接口及子接口实现(Home) | 业务类更“轻”,可测试性更强 |
| 访问方式 | 官方更推荐 DI(push),少用 getBean(pull)(Home) | 降低耦合,避免“到处找容器” |
一句大白话:容器是用来“托管依赖”的,不是让你把它当“全局变量”到处取;否则你的架构就会从“治理”滑向“失控”。
对比图:BeanFactory vs ApplicationContext(选型一眼定)
| 能力维度 | BeanFactory | ApplicationContext |
|---|---|---|
| 核心定位 | 最小容器视图(取 Bean、判类型/作用域等)(Home) | “应用级”容器:在 BeanFactory 之上叠加能力(Home) |
| 增强能力 | 不强调事件/资源/i18n | 内建 事件发布、消息国际化、资源加载、父子上下文(Home) |
| 工程建议 | 更偏框架内部/底层 | 绝大多数业务系统默认选择它 |
工作流程图:一次 getBean() 背后的“交付链路” 🔧
...置处理等] G --> H[放入缓存(若为单例)] H --> I[返回 ----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'
你可以把它当成一条“组件交付流水线”:输入是 BeanDefinition,输出是可用的业务对象;而 DefaultListableBeanFactory 是最常见的“全功能实现”。(Home)
代码示例:用 DefaultListableBeanFactory 手动注册并获取 Bean(含逐行解释)🙂
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(DemoService.class);
bf.registerBeanDefinition("demoService", bd);
DemoService s1 = bf.getBean("demoService", DemoService.class);
DemoService s2 = bf.getBean(DemoService.class);
System.out.println(s1 == s2);
bf.preInstantiateSingletons();
解释(逐行对齐):
new DefaultListableBeanFactory():创建一个“可注册 BeanDefinition 的工厂”,它是 Spring 默认的全功能 BeanFactory 实现之一,支持基于元数据创建 Bean 且可被后处理器扩展。(Home)new RootBeanDefinition(DemoService.class):用“元数据”描述一个 Bean:它的类型是DemoService,后续由容器按规则实例化/装配。registerBeanDefinition("demoService", bd):把元数据注册进容器,“demoService”就是该 Bean 的唯一名字。getBean("demoService", DemoService.class):按名称+类型获取 Bean;若未创建,容器会按流程图完成创建与装配。getBean(DemoService.class):按类型获取(当类型唯一时很方便)。System.out.println(s1 == s2):验证是否同一实例;若该 Bean 默认是 singleton,通常会输出true。preInstantiateSingletons():显式触发“把所有非 lazy 的单例提前实例化”,并会考虑 FactoryBean 情况;通常在容器完成装配后执行,用于把启动期风险前置暴露(例如配置错误尽早失败)。(Home)
落地建议:把 BeanFactory 当成“底座”,把复杂度留在容器里
已经是第一篇啦!
下一篇: 服务器路由命令有哪些常用技巧?