前言
在 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. 主要区别对比表、
| 特性 | beanfactory | factorybean |
|---|---|---|
| 类型 | 接口 (interface) | 接口 (interface) |
| 所属包 | org.springframework.beans.factory.beanfactory | org.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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论