Spring BeanFactory和FactoryBean的详细对比和解析

 更新时间:2026年07月23日 09:41:20   作者:程序员从入门到入土  
在Spring框架中BeanFactory和FactoryBean虽然名称相似,但功能和角色截然不同,这篇文章主要介绍了Spring BeanFactory和FactoryBean详细对比和解析的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在 Spring 框架中,BeanFactory 和 FactoryBean 虽然名字相似,但它们的角色、职责和使用场景有着本质的区别。简单来说,‌BeanFactory 是管理 Bean 的容器(工厂本身),而 FactoryBean 是一种特殊的 Bean,它用于创建其他 Bean(工厂生产的产品或辅助工具)‌。

以下是两者的详细对比和解析:

1. 核心定义与角色

BeanFactory(IOC 容器)‌

  • 定义‌:它是 Spring IOC 容器的顶级接口,代表了 Spring 容器本身。
  • 角色‌:它是“工厂”的管理者。负责实例化、配置和管理应用程序中的所有 Bean。
  • 本质‌:它是一个基础设施组件,用于存储 Bean 定义(BeanDefinition),并根据这些定义创建 Bean 实例。
  • 常见实现‌:DefaultListableBeanFactory、ApplicationContext(内部持有一个 BeanFactory)。

FactoryBean(特殊 Bean)‌

  • 定义‌:它是一个接口 (org.springframework.beans.factory.FactoryBean),用户可以实现该接口来定义复杂的 Bean 创建逻辑。
  • 角色‌:它是容器中的一个“特殊员工”。当容器需要获取这个 Bean 时,不会直接返回 FactoryBean 实例本身,而是调用其 getObject() 方法来获取它所创建的对象。
  • 本质‌:它是一种设计模式的应用(工厂模式),允许开发者自定义 Bean 的实例化过程,常用于集成第三方框架或创建复杂对象。

2. 主要区别对比表、

特性BeanFactoryFactoryBean
‌类型‌接口 (Interface)接口 (Interface)
‌所属包‌org.springframework.beans.factory.BeanFactoryorg.springframework.beans.factory.FactoryBean
‌核心职责‌管理所有 Bean 的生命周期、依赖注入、获取 Bean自定义单个或特定类型 Bean 的创建逻辑
‌身份‌‌容器‌ (Container)‌Bean‌ (Component)
‌获取方式‌通过上下文获取容器实例,再调用 getBean()作为普通 Bean 注册到容器中,通过 getBean() 获取其创建的对象
‌默认行为‌不直接作为 Bean 被业务代码使用,而是作为底层支撑默认返回 getObject() 产生的对象,而非 FactoryBean 本身
‌典型场景‌Spring 启动时的核心组件集成 MyBatis (SqlSessionFactoryBean)、AOP 代理对象创建等

3. 深入理解 FactoryBean 的工作机制

FactoryBean 的核心在于它改变了 Spring 获取 Bean 的默认行为。

‌正常 Bean‌:当你请求一个名为 myBean 的 Bean 时,Spring 返回该类的实例。
‌FactoryBean‌:当你请求一个实现了 FactoryBean 接口的 Bean(例如 myFactoryBean)时:
Spring 会先创建 myFactoryBean 的实例。
Spring 检测到它实现了 FactoryBean 接口。
Spring 调用 myFactoryBean.getObject() 方法。
‌最终返回给调用者的是 getObject() 返回的对象,而不是 myFactoryBean 本身。‌
如何获取 FactoryBean 本身?
如果你确实需要获取 FactoryBean 实例本身(而不是它创建的对象),需要在 Bean 名称前加上 & 前缀。

context.getBean(“myFactoryBean”) -> 返回 getObject() 的结果。
context.getBean(“&myFactoryBean”) -> 返回 FactoryBean 实例本身。

4. 代码示例

BeanFactory 的使用(通常由 Spring 内部管理)

// ApplicationContext 内部包含 BeanFactory
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 通过 BeanFactory 的功能获取 Bean
MyService service = context.getBean(MyService.class);

FactoryBean 的实现与使用
假设我们需要创建一个复杂的 Connection 对象:

// 1. 定义 FactoryBean
public class ConnectionFactoryBean implements FactoryBean<Connection> {

    @Override
    public Connection getObject() throws Exception {
        // 自定义复杂的创建逻辑
        return DriverManager.getConnection("jdbc:mysql://...", "user", "pass");
    }

    @Override
    public Class<?> getObjectType() {
        return Connection.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
<!-- 2. 在配置文件中注册 -->
<bean id="connectionFactory" class="com.example.ConnectionFactoryBean"/>
// 3. 使用
// 获取的是 Connection 对象,而不是 ConnectionFactoryBean 对象
Connection conn = context.getBean("connectionFactory", Connection.class);

// 如果非要获取 FactoryBean 本身
ConnectionFactoryBean factory = context.getBean("&connectionFactory", ConnectionFactoryBean.class);

5. 总结

‌BeanFactory‌ 是 Spring 的‌心脏‌,它负责整个应用上下文中所有 Bean 的管理。它是框架的基础设施。

‌FactoryBean‌ 是 Spring 提供的一种‌扩展机制‌,它允许开发者介入 Bean 的创建过程。它是框架中的一种特殊组件,用于处理那些无法通过简单构造函数或 setter 注入创建的复杂对象。

可以这样比喻:

‌BeanFactory‌ 是整个‌汽车制造厂‌。
‌FactoryBean‌ 是制造厂里的一条‌特殊生产线‌(比如专门定制引擎的生产线)。
当你向制造厂(BeanFactory)请求“引擎”时,它会通过那条特殊生产线(FactoryBean)为你生产出引擎,而不是把生产线本身搬给你。

到此这篇关于Spring BeanFactory和FactoryBean的详细对比和解析的文章就介绍到这了,更多相关Spring BeanFactory和FactoryBean内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文带你搞懂Java中线程的创建方式

    一文带你搞懂Java中线程的创建方式

    这篇文章主要为大家详细介绍了Java中线程的创建方式的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解一下
    2023-03-03
  • idea2020最新版配置maven的方法

    idea2020最新版配置maven的方法

    这篇文章主要介绍了idea2020最新版配置maven的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • 浅析Spring获取Bean的九种方法详解

    浅析Spring获取Bean的九种方法详解

    随着SpringBoot的普及,Spring的使用也越来越广,在某些场景下,我们无法通过注解或配置的形式直接获取到某个Bean。比如,在某一些工具类、设计模式实现中需要使用到Spring容器管理的Bean,此时就需要直接获取到对应的Bean,这篇文章主要介绍了Spring获取Bean的九种方法
    2023-01-01
  • Mybatis批处理、Mysql深分页操作

    Mybatis批处理、Mysql深分页操作

    这篇文章主要介绍了Mybatis批处理、Mysql深分页操作,Mybatis批量操作包括Foreach方式和ExecutorType.BATCH插入操作,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • springAOP的三种实现方式示例代码

    springAOP的三种实现方式示例代码

    这篇文章主要介绍了springAOP的三种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • java 线程池的实现方法

    java 线程池的实现方法

    在本篇文章里小编给大家整理了关于java 线程池的实现方法,有兴趣的朋友们可以学习参考下。
    2020-02-02
  • Spring源码BeanFactoryPostProcessor详解

    Spring源码BeanFactoryPostProcessor详解

    BeanFactoryPostProcessor的执行时机是在Spring扫描完成后,Bean初始化前,当我们实现BeanFactoryPostProcessor接口,可以在Bean的初始化之前对Bean进行属性的修改,下面通过本文看下Spring源码分析-BeanFactoryPostProcessor的实例代码,感兴趣的朋友一起看看吧
    2021-11-11
  • @PathVariable 如何自动填充入实例对象中

    @PathVariable 如何自动填充入实例对象中

    这篇文章主要介绍了@PathVariable 实现自动填充入实例对象中的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • JAVA中哈希表HashMap的深入学习

    JAVA中哈希表HashMap的深入学习

    这篇文章主要介绍了哈希表HashMap的深入学习,哈希表是一种非常重要的数据结构,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中HashMap的实现原理进行讲解。感兴趣的话可以一起来学习
    2020-07-07
  • Java ConcurrentHashMap锁分段机制使用及代码实例

    Java ConcurrentHashMap锁分段机制使用及代码实例

    ConcurrentHashMap是Java中的一种线程安全的哈希表,通过锁分段机制提高了并发性能,在Java 8中,ConcurrentHashMap引入了CAS操作和更复杂的节点继承结构,进一步优化了并发操作
    2025-01-01

最新评论