推理思路: 从 BeanFactory 接口出发,逐层查看其子接口 ListableBeanFactory、HierarchicalBeanFactory、AutowireCapableBeanFactory,再追踪 ApplicationContext 的继承树,画出完整的接口图谱。核心追问:ApplicationContext 比 BeanFactory 多了什么能力?这些能力从何而来?
ListableBeanFactory、HierarchicalBeanFactory、AutowireCapableBeanFactory 三者彼此平行,并不互相继承,对应容器三种正交能力:
子接口 | 解决的本质问题 | 对应"动词" |
|---|---|---|
BeanFactory(基类) | 按名/类型取一个 bean | get |
ListableBeanFactory | 遍历枚举所有 bean | list |
HierarchicalBeanFactory | 容器父子层叠(子覆盖父) | delegate |
AutowireCapableBeanFactory | 自动注入依赖(容器推,不靠用户拉) | wire |
第一性原理:单一职责 + 接口隔离原则(ISP)。Spring 没有把这些能力塞进一个大接口,而是按"语义动词"拆分,让 DefaultListableBeanFactory 同时实现它们,从而具备完整能力——这是 Java SPI 设计的范本。
ApplicationContext 真正的杀手锏,不是那些继承的接口,而是 AbstractApplicationContext.refresh()(约 581 行起)的"自动注册"约定:
步骤(来自 refresh()) | BeanFactory 的行为 | ApplicationContext 的行为 |
|---|---|---|
registerBeanPostProcessors | 不做 | 自动扫并注册所有 BPP |
registerApplicationListeners | 不做 | 自动扫并注册所有 ApplicationListener |
finishBeanFactoryInitialization | 需要用户手动 getBean 才会创建 | 预实例化所有非 lazy 单例(急加载) |
initMessageSource | 不做 | 自动具备 i18n |
initApplicationEventMulticaster | 不做 | 自动具备事件总线 |
第一性原理解读:
BeanFactory 是 "惰性工厂(lazy factory)" —— 你不问我就不做;ApplicationContext 是 "主动容器(eager container)" —— 启动时把基础设施(事件、国际化、后置处理器)一切就绪,约定优于配置。这也是为什么 Spring 推荐业务代码 99% 场景用 ApplicationContext,只有在极简场景(如纯配置加载、嵌入第三方框架)才退回到 BeanFactory。
ConfigurableApplicationContext(spring-context/.../ConfigurableApplicationContext.java):可配置/可刷新的 ApplicationContext,是启动期操作的接口(refresh()、close())。这就是为什么 ClassPathXmlApplicationContext、AnnotationConfigApplicationContext 都要实现它,否则没法 refresh。BeanDefinitionRegistry:ApplicationContext 内部那个 DefaultListableBeanFactory 还实现了 BeanDefinitionRegistry,承担 "注册 BeanDefinition" 的职责,但 ApplicationContext 自身不再继承它,因为注册动作只在启动期进行,不属于运行时 client API。Spring 把"管理对象"这件事按"动词"拆成 4 个正交接口(取/列/层叠/注入),又按"运行时/启动期"拆成 2 个层次(
BeanFactory运行时按需取,ApplicationContext启动期主动装配一切)。前者是基础设施,后者是企业级容器入口。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。