1. 核心角色与定义
-
BeanFactory:
- 角色: IoC 容器的根接口。
- 定义: 它是 Spring IoC 容器最基础、最底层的接口。它定义了容器管理 Bean 的核心方法 ,例如:
getBean(String name)
: 根据名称获取 Bean 实例。getBean(Class<T> requiredType)
: 根据类型获取 Bean 实例。containsBean(String name)
: 判断容器是否包含指定名称的 Bean。isSingleton(String name)
: 判断指定名称的 Bean 是否是单例。getType(String name)
: 获取指定名称 Bean 的类型。getAliases(String name)
: 获取指定名称 Bean 的别名。
- 本质: 它是一个对象工厂 ,负责存储、管理和提供 Bean 实例 。它是 Spring IoC 容器功能的基础骨架。我们通常使用的
ApplicationContext
(如ClassPathXmlApplicationContext
,AnnotationConfigApplicationContext
) 是BeanFactory
的高级子接口,提供了更多企业级功能(如事件发布、国际化、资源访问等)。
-
FactoryBean:
- 角色: 创建复杂对象的特殊 Bean。
- 定义: 它是一个接口 ,实现该接口的类本身是一个被 Spring 管理的 Bean 。但这个 Bean 的主要职责不是提供自身实例,而是负责创建并返回另一个特定类型的对象。
- 核心方法:
T getObject()
: 最重要 的方法。实现此方法创建并返回目标对象实例 。这个对象才是最终需要被注入或通过getBean()
获取到的对象。Class<?> getObjectType()
: 返回getObject()
方法所创建对象的类型。boolean isSingleton()
: 指示getObject()
返回的对象是否是单例。通常返回true
。
- 本质: 它是一种生产机制 ,封装了创建复杂、有状态、需要特殊初始化逻辑或难以直接通过简单构造创建的对象的逻辑。它本身也是一个 Bean,但其价值在于它生产的产品。
2. 关键区别总结
特性 | BeanFactory | FactoryBean |
---|---|---|
核心角色 | IoC 容器本身 (容器根接口) | 特殊 Bean (对象工厂) |
作用 | 管理所有 Bean 的生命周期、依赖注入和提供 | 封装复杂对象的创建逻辑,生产另一个对象 |
本质 | 容器 / 对象仓库 / 管理者 | 生产者 / 工厂 (本身也是被管理的 Bean) |
目标对象 | 直接管理并暴露 Bean 实例 | 通过 getObject() 方法暴露其创建的目标对象实例 |
获取方式 | getBean("beanName") 直接获取目标 Bean 实例 |
getBean("&factoryBeanName") 获取 FactoryBean 本身 getBean("factoryBeanName") 获取 FactoryBean 创建的目标对象 |
使用场景 | 任何需要 Spring IoC 容器管理 Bean 的场景 | 创建需要复杂初始化、依赖外部资源、代理对象、集成第三方库对象(如 SqlSessionFactory)等场景 |
类比 | 超级工厂,管理所有生产线和产品仓库 | 工厂中的一条特殊生产线,专门生产某种复杂产品 |
3. 使用方式与示例
-
BeanFactory 使用:
- 通常不直接使用
BeanFactory
接口,而是使用其增强子接口ApplicationContext
。 - 通过
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
或new ClassPathXmlApplicationContext("applicationContext.xml");
启动容器。 - 通过
ctx.getBean(MyService.class)
或ctx.getBean("myService")
获取 Bean 实例。
- 通常不直接使用
-
FactoryBean 使用:
-
步骤 1: 创建一个类实现
FactoryBean<T>
接口 (T
是目标对象类型)。 -
步骤 2: 实现
getObject()
,getObjectType()
,isSingleton()
方法。 -
步骤 3: 将这个实现类作为一个普通的 Bean 注册到 Spring 容器中(通过
@Bean
,@Component
, XML<bean>
等)。 -
示例: 创建一个生产
Connection
对象的ConnectionFactoryBean
(简化示例):javapublic class ConnectionFactoryBean implements FactoryBean<Connection> { private String url; private String username; private String password; // ... setters for properties ... @Override public Connection getObject() throws Exception { // 复杂的连接创建和初始化逻辑 return DriverManager.getConnection(url, username, password); } @Override public Class<?> getObjectType() { return Connection.class; } @Override public boolean isSingleton() { return false; // 通常数据库连接不是单例 } }
-
注册: (假设使用 Java Config)
java@Configuration public class AppConfig { @Bean public ConnectionFactoryBean dataSourceConnection() { ConnectionFactoryBean factory = new ConnectionFactoryBean(); factory.setUrl("jdbc:mysql://localhost:3306/mydb"); factory.setUsername("root"); factory.setPassword("secret"); return factory; } }
-
获取:
javaApplicationContext ctx = ...; // 获取 FactoryBean 创建的目标对象 (Connection) Connection conn = ctx.getBean("dataSourceConnection"); // 注意:bean name 是注册的 FactoryBean 的名字 // 获取 FactoryBean 本身 ConnectionFactoryBean factoryBean = ctx.getBean("&dataSourceConnection"); // 注意:加 '&' 前缀
-
4. 常见应用场景
- BeanFactory:
- 所有需要 Spring IoC 容器进行依赖注入、Bean 生命周期管理的场景。
- 框架扩展的基础(如集成其他容器)。
- FactoryBean:
- 集成第三方库: 将非 Spring 管理的对象(如 MyBatis 的
SqlSessionFactory
, Hibernate 的SessionFactory
, JPA 的EntityManagerFactory
)包装成 Spring Bean 的标准方式。Spring 通常提供现成的FactoryBean
实现 (如SqlSessionFactoryBean
)。 - 创建代理对象: 如 AOP 代理、事务代理。
ProxyFactoryBean
是 Spring AOP 的核心类之一。 - 创建有复杂初始化逻辑的对象: 对象创建需要多步操作、依赖外部资源(文件、网络)、异常处理等。
- 创建遗留代码或难以修改代码的对象: 当无法直接在目标类上添加
@Component
或修改其构造方法时。 - 创建需要动态决定实现的对象: 根据配置或运行时环境返回不同的具体实现。
- 创建对象池: 管理可重用的对象实例。
- 集成第三方库: 将非 Spring 管理的对象(如 MyBatis 的
5. 关键点与注意事项
- 名称相似,本质不同: 这是最大的混淆点。
BeanFactory
是容器,FactoryBean
是容器中一个特殊的"工人"(Bean)。 getBean()
的行为: 对注册的FactoryBean
的 bean name (例如"myFactoryBean"
) 调用getBean()
:ctx.getBean("myFactoryBean")
-> 返回FactoryBean.getObject()
方法创建的对象(目标对象)。ctx.getBean("&myFactoryBean")
-> 返回FactoryBean
实例本身。&
前缀是获取FactoryBean
本身的关键。
- 间接性:
FactoryBean
在容器和最终的目标对象之间增加了一层间接性。容器直接管理的是FactoryBean
实例,而目标对象是由FactoryBean
创建并间接提供的。 ApplicationContext
自动检测:ApplicationContext
会自动检测所有实现了FactoryBean
接口的 Bean,并在适当的时候调用其getObject()
方法来获取目标对象。- 配置简化:
FactoryBean
极大地简化了在 Spring 配置中创建复杂对象的流程,将复杂的创建逻辑封装在 Java 代码中,配置只需要关注FactoryBean
本身的属性设置。
总结
BeanFactory
是 Spring IoC 容器的基石。 它是管理者 ,定义了容器如何存储、管理和提供所有 Bean 的核心契约。它是"大工厂"。FactoryBean
是用于创建特定复杂对象的特殊 Bean。 它是生产者 ,本身是一个被容器管理的 Bean,但其核心价值在于它实现了getObject()
方法来制造另一个对象 。它是"工厂中的特殊生产线"。
理解 FactoryBean
和 BeanFactory
的区别对于深入掌握 Spring 的 IoC 机制、理解 Spring 如何集成第三方库以及处理复杂对象的创建至关重要。记住 &
前缀的用法是区分获取 FactoryBean
本身和其生产的目标对象的关键。