服务公告

服务公告 > Linux命令 > 蓝易云:Spring之BeanFactory

蓝易云: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() 背后的“交付链路” 🔧

Syntax error in textmermaid version 10.8.0
Parse error on line 8:
...置处理等] 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 当成“底座”,把复杂度留在容器里

  1. 业务代码优先走 DI,少写“到处 getBean()”。(Home)
  2. 需要企业级能力(事件、资源、i18n、层级上下文)就用 ApplicationContext;别硬把“螺丝刀”当“瑞士军刀”。(Home)
  3. 启动稳定性要求高的系统,可在关键模块引入“单例预实例化”策略,把问题暴露在启动阶段,而不是线上流量阶段。(Home)

已经是第一篇啦!

下一篇: 服务器路由命令有哪些常用技巧?