BeanFactory 和 ApplicationContext 有什么区别
BeanFactory 可以理解为含有 bean 集合的工厂类。BeanFactory 包含了种 bean 的定义,以便在接收到客户端请求时将对应的 bean 实例化。
BeanFactory 还能在实例化对象的时生成协作类之间的关系。此举将 bean 自身与 bean 客户端的配置中解放出来。BeanFactory 还包含了 bean 生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。
从表面上看,ApplicationContext 如同 BeanFactory 一样具有 bean 定义、bean 关联关系的设置,根据请求分发 bean 的功能。但 ApplicationContext 在此基础上还提供了其他的功能:
- 提供了支持国际化的文本消息
- 统一的资源文件读取方式
- 已在监听器中注册的 bean 的事件
功能清单之外,两者最本质的差异只有一条:bean 的实例化时机——懒加载 vs 启动时预实例化。这条差异派生了启动性能、错误暴露时机、内存占用等所有工程区别。本文以此为主线展开。
核心差异:实例化时机
- BeanFactory:getBean 时才实例化(懒加载)。容器启动只解析注册 bean 定义(BeanDefinition),不创建实例
- ApplicationContext:refresh 阶段就对所有非懒加载单例预实例化(finishBeanFactoryInitialization 中 preInstantiateSingletons)
派生影响:
| 维度 | BeanFactory | ApplicationContext |
|---|---|---|
| 启动速度 | 快(不建实例) | 慢(预建全部单例) |
| 配置错误暴露 | 第一次 getBean 才爆 | 启动即爆(fail-fast,生产友好) |
| 内存 | 按需 | 启动即占满单例 |
| AOP/后处理器 | 需手动注册 | 自动应用 BeanPostProcessor |
| 事件/国际化/资源加载 | 无 | 内建(ApplicationEventPublisher/MessageSource/ResourceLoader) |
| Web 集成 | 无 | WebApplicationContext 族 |
接口谱系:ApplicationContext 是超集
ApplicationContext 继承链:ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver...。即它首先是完整的 BeanFactory,再叠加企业级设施。所以”区别”准确说是”基础容器 vs 全功能容器”,而非两种平行实现。
为什么生产永远用 ApplicationContext
- fail-fast:Bean 定义错误、依赖缺失、循环依赖(构造器级)在启动时暴露,而不是凌晨三点第一次被调用时
- 后处理器自动生效:@Autowired 注入、@PostConstruct、AOP 代理都依赖 BeanPostProcessor 的注册与应用——裸 BeanFactory 下这些注解”不工作”,是新手最常见的困惑来源
- 事件机制:ApplicationEvent 发布/监听是框架与业务解耦的基础设施(如监听 ContextRefreshedEvent 做启动后初始化)
- Web 必需:Servlet 容器集成(ContextLoaderListener)只认 WebApplicationContext
BeanFactory 的今天的位置:内部 SPI 与极端受限环境(如嵌入式/内存敏感场景手动控制实例化),以及源码阅读时理解容器核心的入口(DefaultListableBeanFactory 才是真正干活的类,ApplicationContext 是把功能组装起来的外壳)。
一个验证性实验
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); |
两行对比即全部区别的实证:时机 + 后处理器。
面试答法
一句话版:BeanFactory 是最基础的 IoC 容器 SPI,懒加载、功能最小;ApplicationContext 在其上预实例化单例并集成事件、国际化、资源加载与后处理器自动应用,是应用开发的唯一选择;两者差异的根是实例化时机,其余都是派生。











