Spring BeanFactory和FactoryBean的区别
在 Spring 框架中BeanFactory 和 FactoryBean 虽然名字相似但它们的角色、职责和使用场景有着本质的区别。简单来说BeanFactory 是管理 Bean 的容器工厂本身而 FactoryBean 是一种特殊的 Bean它用于创建其他 Bean工厂生产的产品或辅助工具。以下是两者的详细对比和解析1. 核心定义与角色BeanFactoryIOC 容器定义它是 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 内部包含 BeanFactoryApplicationContextcontextnewClassPathXmlApplicationContext(beans.xml);// 通过 BeanFactory 的功能获取 BeanMyServiceservicecontext.getBean(MyService.class);FactoryBean 的实现与使用假设我们需要创建一个复杂的 Connection 对象// 1. 定义 FactoryBeanpublicclassConnectionFactoryBeanimplementsFactoryBeanConnection{OverridepublicConnectiongetObject()throwsException{// 自定义复杂的创建逻辑returnDriverManager.getConnection(jdbc:mysql://...,user,pass);}OverridepublicClass?getObjectType(){returnConnection.class;}OverridepublicbooleanisSingleton(){returntrue;}}!-- 2. 在配置文件中注册 --beanidconnectionFactoryclasscom.example.ConnectionFactoryBean/// 3. 使用// 获取的是 Connection 对象而不是 ConnectionFactoryBean 对象Connectionconncontext.getBean(connectionFactory,Connection.class);// 如果非要获取 FactoryBean 本身ConnectionFactoryBeanfactorycontext.getBean(connectionFactory,ConnectionFactoryBean.class);5. 总结BeanFactory 是 Spring 的心脏它负责整个应用上下文中所有 Bean 的管理。它是框架的基础设施。FactoryBean 是 Spring 提供的一种扩展机制它允许开发者介入 Bean 的创建过程。它是框架中的一种特殊组件用于处理那些无法通过简单构造函数或 setter 注入创建的复杂对象。可以这样比喻BeanFactory 是整个汽车制造厂。FactoryBean 是制造厂里的一条特殊生产线比如专门定制引擎的生产线。当你向制造厂BeanFactory请求“引擎”时它会通过那条特殊生产线FactoryBean为你生产出引擎而不是把生产线本身搬给你。