news 2026/3/17 2:50:19

BeanFactory 和 FactoryBean区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BeanFactory 和 FactoryBean区别

简单来说,BeanFactorySpring IoC 容器的根接口(“容器本身”),而FactoryBean自定义 Bean 创建逻辑的工厂接口(“创建 Bean 的工厂”),两者的角色和职责天差地别。

一、核心概念与区别(先看表格,一目了然)

维度BeanFactoryFactoryBean
核心定位Spring IoC 容器的根接口(“容器”)特殊的 Bean 类型(“工厂 Bean”),用于创建复杂 Bean
核心作用管理所有 Bean 的生命周期(实例化、配置、依赖注入、获取 Bean)自定义 Bean 的创建过程(解决复杂 Bean 的初始化问题)
使用方式开发者直接调用其方法(如getBean())获取 Bean开发者实现该接口,Spring 自动调用其方法创建 Bean
核心方法getBean(String name)containsBean()getObject()getObjectType()isSingleton()
关系是所有 Spring 容器的基础,包含 / 管理 FactoryBean是被 BeanFactory 管理的一种特殊 Bean

二、详细解析 + 代码示例

1. BeanFactory:Spring IoC 容器的 “根”

BeanFactory是 Spring 最基础的 IoC 容器接口,定义了 IoC 容器的核心规范:负责定位、加载、实例化、配置 Bean,并提供 Bean 的获取和管理能力

你可以把它理解为 “Bean 的仓库管理员”—— 所有 Bean 都由它管理,你要获取 Bean 时,只需告诉它 Bean 的名称 / 类型,它就会返回对应的实例。

核心特点:
  • 是 ApplicationContext(我们常用的容器)的父接口,ApplicationContext 在其基础上扩展了国际化、事件发布、资源加载等功能;
  • 采用延迟加载(懒加载):只有调用getBean()时才实例化 Bean(ApplicationContext 默认预加载);
  • 所有 Spring 容器都实现了该接口(如DefaultListableBeanFactoryXmlBeanFactory)。
代码示例:使用 BeanFactory 获取 Bean
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; // 普通Bean类 class User { private String name; // 构造器、getter/setter省略 public User(String name) { this.name = name; } @Override public String toString() { return "User{name='" + name + "'}"; } } public class BeanFactoryDemo { public static void main(String[] args) { // 1. 创建BeanFactory容器(加载xml配置,模拟传统方式) BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml")); // 2. 从容器中获取Bean(此时才实例化User) User user = (User) beanFactory.getBean("user"); System.out.println(user); // 输出:User{name='张三'} } } // beans.xml配置(放在resources目录下) /* <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="User"> <constructor-arg value="张三"/> </bean> </beans> */
2. FactoryBean:自定义 Bean 创建的 “工厂”

FactoryBean是一个特殊的 Bean 接口—— 当 Spring 容器发现一个 Bean 实现了FactoryBean,不会直接返回这个 Bean 本身,而是调用它的getObject()方法,返回该方法创建的实例。

你可以把它理解为 “复杂 Bean 的定制化工厂”:当某个 Bean 的创建逻辑很复杂(比如需要连接数据库、初始化第三方组件、多步配置),直接通过 xml / 注解配置太繁琐时,就可以实现FactoryBean来封装创建逻辑。

核心方法:
方法名作用
T getObject()核心方法,返回最终要使用的 Bean 实例
Class<?> getObjectType()返回getObject()创建的 Bean 的类型
boolean isSingleton()返回创建的 Bean 是否为单例(默认 true)
代码示例:实现 FactoryBean 创建复杂 Bean

比如创建一个需要初始化的RedisConnectionBean(模拟复杂 Bean):

import org.springframework.beans.factory.FactoryBean; // 模拟复杂的Redis连接类 class RedisConnection { private String host; private int port; // 复杂初始化逻辑:比如建立连接、认证等 public RedisConnection(String host, int port) { this.host = host; this.port = port; System.out.println("初始化Redis连接:" + host + ":" + port); } @Override public String toString() { return "RedisConnection{host='" + host + "', port=" + port + "}"; } } // 实现FactoryBean,封装RedisConnection的创建逻辑 class RedisConnectionFactoryBean implements FactoryBean<RedisConnection> { private String host; private int port; // 配置参数(可通过xml/注解注入) public void setHost(String host) { this.host = host; } public void setPort(int port) { this.port = port; } // 核心:创建RedisConnection实例 @Override public RedisConnection getObject() throws Exception { // 这里可以写复杂的创建逻辑:比如读取配置、校验参数、初始化连接池等 return new RedisConnection(host, port); } // 返回创建的Bean类型 @Override public Class<?> getObjectType() { return RedisConnection.class; } // 单例模式(默认true) @Override public boolean isSingleton() { return true; } } // 测试使用FactoryBean public class FactoryBeanDemo { public static void main(String[] args) { // 1. 创建Spring容器 BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml")); // 2. 获取Bean:容器会调用RedisConnectionFactoryBean的getObject(),返回RedisConnection RedisConnection redisConn = (RedisConnection) beanFactory.getBean("redisConnection"); System.out.println(redisConn); // 输出:RedisConnection{host='127.0.0.1', port=6379} // 3. 若要获取FactoryBean本身(而非它创建的Bean),需在名称前加& RedisConnectionFactoryBean factoryBean = (RedisConnectionFactoryBean) beanFactory.getBean("&redisConnection"); System.out.println(factoryBean); // 输出FactoryBean实例本身 } } // beans.xml配置 /* <bean id="redisConnection" class="RedisConnectionFactoryBean"> <property name="host" value="127.0.0.1"/> <property name="port" value="6379"/> </bean> */

三、关键补充:容易踩的坑

  1. 获取 FactoryBean 本身的方式:默认beanFactory.getBean("xxx")返回的是FactoryBean创建的 Bean;若要获取FactoryBean实例本身,需在 Bean 名称前加&(如&redisConnection)。
  2. FactoryBean 的适用场景
    • 整合第三方组件(如 MyBatis 的SqlSessionFactoryBean、Redis 的RedisTemplateFactoryBean);
    • 创建需要复杂初始化逻辑的 Bean(如连接池、线程池、分布式锁客户端);
    • 动态创建 Bean(根据不同配置返回不同实例)。
  3. BeanFactory 的扩展:日常开发中很少直接使用BeanFactory,而是用它的子接口ApplicationContext(包含 BeanFactory 所有功能,且支持注解、事件、国际化等)。

总结

  1. 角色本质不同BeanFactory是 Spring IoC 容器的核心接口(“容器”),管理所有 Bean;FactoryBean是特殊的 Bean(“工厂”),用于创建特定的复杂 Bean。
  2. 使用目的不同BeanFactory解决 “Bean 的统一管理” 问题;FactoryBean解决 “复杂 Bean 的定制化创建” 问题。
  3. 调用逻辑不同:开发者调用BeanFactorygetBean()获取 Bean;Spring 容器调用FactoryBeangetObject()生成 Bean。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/15 11:12:00

阿西米尼Asciminib用于慢性髓系白血病治疗的每日两次口服标准剂量

阿西米尼&#xff08;Asciminib&#xff09;作为全球首个STAMP抑制剂&#xff0c;凭借其独特的靶向ABL肉豆蔻酰口袋的机制&#xff0c;为慢性髓系白血病&#xff08;CML&#xff09;患者提供了突破性治疗选择。其每日两次口服方案在耐药患者中展现出显著疗效&#xff0c;尤其针…

作者头像 李华
网站建设 2026/3/15 12:57:17

开题报告 springboot和vue病例管理系统

目录系统背景与意义技术选型核心功能模块创新点技术难点与解决方案项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作系统背景与意义 基于SpringBoot和Vue的病例管理系统旨在解决传统医疗信息管理中的低效问…

作者头像 李华
网站建设 2026/3/15 16:46:17

基于深度学习YOLOv12的垃圾分类识别检测系统(YOLOv12+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)

一、项目介绍 随着城市化进程加快&#xff0c;垃圾分类已成为环保领域的重要议题。传统垃圾分类方法依赖人工分拣&#xff0c;效率低且成本高。为此&#xff0c;本研究基于YOLOv12深度学习算法&#xff0c;开发了一套高效准确的垃圾分类识别检测系统。系统针对4类垃圾&#xf…

作者头像 李华
网站建设 2026/3/15 22:25:23

GraphRAG全解析:用知识图谱解决大模型多跳推理难题

GraphRAG通过引入知识图谱解决传统RAG无法处理的多跳推理问题。它将文本切分为单元&#xff0c;提取实体和关系构建知识图谱&#xff0c;进行社区检测并生成报告。检索分为局部和全局两种方式&#xff0c;前者关注特定实体细节&#xff0c;后者提供全局视角。GraphRAG能有效提高…

作者头像 李华
网站建设 2026/3/15 16:46:10

计算机PHP毕设实战-基于PHP的农村智慧社区系统设计与开发养老资讯管理医护人员、活动信息、养老资讯【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华