【Spring源码】BeanFactory和DefaultListableBeanFactory

DefaultListableBeanFactory 和 BeanFactory 的关系是 接口与实现 的关系,更具体地说,是 核心接口与默认全能实现 的关系。

我们可以用一句话总结:BeanFactory是 Spring 容器的"宪法"(定义了基本规则),而 DefaultListableBeanFactory是这套宪法下最完整、最强大的"政府"(具体执行者)。

下面详细拆解它们的关系:

1. 继承与实现关系(层级结构)

DefaultListableBeanFactory 并非直接实现 BeanFactory 这一个基础接口,而是实现了一个庞大的接口体系。它是 Spring 中功能最全的 BeanFactory 实现类。

层级结构图解:

复制代码
BeanFactory (最顶层的基础接口)
    ↑
    | 继承
ConfigurableBeanFactory (可配置的接口)
    ↑
    | 继承
ConfigurableListableBeanFactory (可配置+可列举的接口)
    ↑
    | 实现
DefaultListableBeanFactory (具体实现类)
    ↑
    | 同时还实现了
BeanDefinitionRegistry (Bean定义注册接口)

关键点解析:

  1. BeanFactory:
    • 这是 Spring IoC 容器的根接口。
    • 它只定义了最基础的行为,比如 getBean(String name)(获取 Bean)、containsBean(String name)(判断是否包含 Bean)。
    • 它不关心 Bean 是怎么定义的,也不关心如何加载配置文件,只管拿 Bean。
  1. ConfigurableBeanFactory:
    • 继承自 BeanFactory。
    • 增加了配置的能力,比如设置类加载器、设置属性编辑器、添加后置处理器等。
  1. ConfigurableListableBeanFactory:
    • 继承自 ConfigurableBeanFactory。
    • 增加了列举 的能力,比如 getBeanDefinitionNames()(获取所有 Bean 的名字)、getBeansOfType()(按类型获取所有 Bean)。
    • 它还提供了分析、修改 Bean 定义的方法,比如 preInstantiateSingletons()(预实例化单例)。
  1. BeanDefinitionRegistry:
    • 这是一个独立的接口 ,不继承 BeanFactory。
    • 它专门负责注册 Bean 定义(registerBeanDefinition)。
    • DefaultListableBeanFactory 实现了这个接口,意味着它不仅能拿 Bean,还能注册和管理 Bean 的定义。

2. 为什么需要 DefaultListableBeanFactory?

既然有了接口 BeanFactory,为什么 Spring 还要搞一个这么复杂的实现类?

因为 BeanFactory 只是一个契约 ,而 DefaultListableBeanFactory 提供了落地实现。它把 Spring 容器启动和运行所需的所有核心功能都集成在了一起:

  • 作为注册表 :它内部维护了一个 Map (beanDefinitionMap),用来存储解析 XML 或注解后生成的 BeanDefinition。
  • 作为工厂 :它实现了 getBean 逻辑,负责创建 Bean 实例、处理循环依赖、执行依赖注入。
  • 作为列表:它实现了按类型查找、遍历所有 Bean 名称的功能。

3. 代码中的体现

在 DefaultListableBeanFactory 的类定义中,你可以清晰地看到这种关系:

复制代码
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    // ...
}
  • extends AbstractAutowireCapableBeanFactory:继承了创建 Bean 的核心逻辑(如自动装配)。
  • implements ConfigurableListableBeanFactory:承诺了"我可以被配置,也可以列举所有 Bean"。
  • implements BeanDefinitionRegistry:承诺了"我可以注册 Bean 定义"。

4. 总结对比

|----------|-------------------|----------------------------|
| 特性 | BeanFactory | DefaultListableBeanFactory |
| 角色 | 接口 | 具体实现类 |
| 职责 | 定义获取 Bean 的基本契约 | 实现 Bean 的注册、创建、依赖注入、查找等全流程 |
| 功能范围 | 极简(只管拿) | 极全(管注册、管创建、管配置、管查找) |
| 使用场景 | 通常作为引用类型持有,面向接口编程 | 实际干活的对象,通常在容器启动时被实例化 |

打个比方:

  • BeanFactory 就像是**"菜单"**,上面写着"你可以点宫保鸡丁"。
  • DefaultListableBeanFactory 就是**"后厨"**,里面有大厨(实例化逻辑)、有仓库(BeanDefinition Map)、有食材(依赖资源),它真正把鸡做熟并端给你。

在 Spring 源码中,ApplicationContext(如 ClassPathXmlApplicationContext)在底层默认就是持有一个 DefaultListableBeanFactory 实例来干脏活累活的。

相关推荐
\光辉岁月/几秒前
15.JavaSE-网络
java·开发语言·网络
const_qiu2 分钟前
第二章 2.4:搭建 Monorepo 骨架 + 共享包 @autix/contracts
java·人工智能·arcgis
兰亭妙微UI设计公司6 分钟前
兰亭妙微软件界面设计公司的解锁按钮设计10大密码
开发语言·前端·javascript
人邮异步社区12 分钟前
C语言好学,还是Python好学?
c语言·开发语言·python
栈帧之外30 分钟前
【C++】红黑树实现
开发语言·c++
程序员老陆31 分钟前
C++中同一个回调函数被多个设备并发调用:并发问题不在“函数”,而在“状态”
开发语言·c++·程序设计
wangchunyu11434 分钟前
JDK8新特性实战(Lambda、Stream、Optional)
java·开发语言
鱼宵38 分钟前
工厂模式实战:消灭魔法数字,把写死的 new 收进一个厂里
开发语言·python
JosieBook1 小时前
【多线程】两台机器同时抢一个字典:一次并发 Bug 的排查
java·网络·bug
niucloud-admin1 小时前
NIUCLOUD LITE AI开发文档--后台系统结构
开发语言