FactoryBean 和 BeanFactory 的傻傻的总是分不清?
引言
记得很久以前经常被问到这样一个面试题"FactoryBean 和 BeanFactory 它们有啥区别"。在 Spring 框架中,BeanFactory
和 FactoryBean
是两个核心概念,虽然名称相似,但它们的角色和功能完全不同。
1. 定义与角色

2. 核心区别

3. 使用场景与示例
(1) BeanFactory 的使用
作用:作为 Spring 容器的根接口,负责管理所有 Bean 的生命周期。
示例:
(2) FactoryBean 的使用
作用:通过自定义
getObject()
方法创建复杂对象。示例:
在 Spring 框架中,FactoryBean
被广泛用于集成第三方中间件或框架,通过封装复杂对象的创建逻辑,简化配置并提高灵活性。以下是几个常见中间件使用 FactoryBean
的示例:
1. MyBatis 的 SqlSessionFactoryBean
作用:创建 MyBatis 的 SqlSessionFactory
实例,集成数据库配置、映射文件扫描等逻辑。
代码示例:
实现原理:
SqlSessionFactoryBean
实现了FactoryBean<SqlSessionFactory>
。getObject()
方法内部调用 MyBatis 的SqlSessionFactoryBuilder
创建SqlSessionFactory
。支持延迟加载和复杂配置(如多数据源、事务管理器)。
2. OpenFeign 的 FeignClientFactoryBean
作用:动态创建 Feign 客户端(RESTful API 调用代理对象)。
代码示例:
实现原理:
FeignClientFactoryBean
封装了 Feign 的Target
和Encoder/Decoder
配置。getObject()
返回动态代理的 Feign 客户端实例。支持自定义拦截器、重试策略等。
3. Redis 的 RedisConnectionFactoryBean
作用:创建 Redis 连接池(如 JedisConnectionFactory
或 LettuceConnectionFactory
)。
代码示例:
实现原理:
JedisConnectionFactory
本身实现了FactoryBean<RedisConnection>
。getObject()
返回RedisConnection
实例(如JedisConnection
)。支持连接池配置(如最大连接数、超时时间)。
4. RocketMQ 的 RocketMQTemplate
作用:封装 RocketMQ 生产者和消费者的创建逻辑。
代码示例:
实现原理:
RocketMQTemplate
通过FactoryBean
模式初始化生产者和消费者。getObject()
返回配置好的RocketMQTemplate
实例。支持消息发送、监听器注册等操作。
5. Quartz 的 SchedulerFactoryBean
作用:创建 Quartz 调度器(Scheduler
),集成任务调度逻辑。
代码示例:
实现原理:
SchedulerFactoryBean
封装了 Quartz 的SchedulerFactory
配置。getObject()
返回Scheduler
实例。支持动态注册任务和触发器。
6. Dubbo 的 ServiceBean
作用:发布 Dubbo 服务,封装服务暴露和注册逻辑。
代码示例:
实现原理:
ServiceBean
实现了FactoryBean<Exporter>
。getObject()
返回服务导出器(Exporter
),完成服务注册和暴露。支持负载均衡、容错策略等 Dubbo 特性。
7. Kafka 的 KafkaTemplate
作用:封装 Kafka 生产者和消费者的创建逻辑。
代码示例:
实现原理:
KafkaTemplate
通过FactoryBean
模式初始化生产者工厂。getObject()
返回配置好的KafkaTemplate
实例。支持消息发送、消费者监听等操作。
总结对比

解耦配置与逻辑:通过
FactoryBean
将复杂初始化逻辑封装,Spring 容器只需管理 Bean 的声明。支持动态创建:可根据运行时条件(如环境变量、配置参数)动态生成不同对象。
统一资源管理:集中管理中间件的连接池、配置参数,便于维护和扩展。
4. 获取 FactoryBean 本身
默认行为:
getBean("factoryBeanName")
返回的是FactoryBean.getObject()
的结果。获取 FactoryBean 实例本身:需在 Bean 名称前加
&
前缀。
5. 常见问题与解决方案
问题 1:混淆 BeanFactory 和 FactoryBean 的功能
解决方案:明确
BeanFactory
是容器,FactoryBean
是创建 Bean 的工具。
问题 2:期望获取 FactoryBean 实例却得到其创建的 Bean
示例:
问题 3:未正确实现 getObjectType()
导致类型检查失败
修复:确保
getObjectType()
返回准确的类型信息。
6. 高级应用场景
(1) 动态代理生成
(2) 延迟初始化
7. 总结

BeanFactory 是 Spring 容器本身,负责管理所有 Bean。
FactoryBean 是 容器中的一个 Bean,负责 生产其他 Bean。
&beanName 是访问 FactoryBean 本身的“密钥”。
文章转载自:java金融
评论