FactoryBean
是 Spring 框架中一个非常重要的接口,它为 Spring IoC 容器提供了更灵活的对象创建方式。
1. FactoryBean
的定义:
FactoryBean
是一个接口,它定义了三个方法:
public interface FactoryBean<T> {
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
getObject()
: 这是最重要的方法。它负责创建并返回一个对象实例。这个对象实例可以是任何类型的对象,不一定是FactoryBean
本身的类型。getObjectType()
: 返回getObject()
方法创建的对象的类型。如果无法在创建对象之前确定类型,可以返回null
。isSingleton()
: 指定getObject()
方法返回的对象是否是单例。默认为true
,表示返回单例对象。
2. FactoryBean
与普通 Bean 的区别:
- 普通 Bean: 当 Spring IoC 容器获取一个普通 Bean 时,它直接返回 Bean 本身的实例。
FactoryBean
: 当 Spring IoC 容器获取一个FactoryBean
时,它有两种选择:- 获取
FactoryBean
本身的实例: 在 Bean 的名称前加上&
符号,例如&myFactoryBean
。 - 获取
FactoryBean
创建的对象: 直接使用 Bean 的名称,例如myFactoryBean
。 Spring 会调用FactoryBean
的getObject()
方法,并返回该方法创建的对象。
- 获取
3. FactoryBean
的工作流程:
- 配置: 在 Spring 配置文件(XML、JavaConfig 等)中定义一个
FactoryBean
的 Bean。 - 容器启动: Spring IoC 容器启动时,会解析配置文件,并创建
FactoryBean
的实例。 - 获取 Bean: 当应用程序通过
getBean()
方法获取FactoryBean
创建的对象时(注意,不是&myFactoryBean
):- Spring 检查该 Bean 是否是一个
FactoryBean
。 - 如果是,Spring 调用
FactoryBean
的getObject()
方法。 getObject()
方法负责创建对象实例,并返回该实例。- Spring 将
getObject()
方法返回的对象放入 Bean 容器中,并返回给应用程序。
- Spring 检查该 Bean 是否是一个
- 获取
FactoryBean
本身: 当应用程序通过getBean("&myFactoryBean")
方法获取FactoryBean
本身的实例时,Spring 直接返回FactoryBean
的实例。
4. FactoryBean
的使用场景:
FactoryBean
主要用于以下场景:
- 创建复杂对象: 当对象的创建逻辑比较复杂,需要多个步骤、依赖多个其他 Bean、或者需要进行一些初始化操作时,可以使用
FactoryBean
。 - 创建代理对象:
FactoryBean
可以用于创建代理对象,例如 AOP 中的代理对象。 - 集成第三方库: 当需要将第三方库创建的对象集成到 Spring 容器中时,可以使用
FactoryBean
。 - 延迟初始化:
FactoryBean
可以延迟对象的创建,直到真正需要使用该对象时才创建。 - 动态创建对象: 可以根据不同情况返回不同对象。
5. 示例:
// 假设有一个复杂的对象 MyComplexObject
public class MyComplexObject {
private String property1;
private int property2;
public MyComplexObject(String property1, int property2) {
this.property1 = property1;
this.property2 = property2;
}
// ... getters and setters ...
}
// 创建一个 FactoryBean 来创建 MyComplexObject
public class MyComplexObjectFactoryBean implements FactoryBean<MyComplexObject> {
private String property1;
private int property2;
public void setProperty1(String property1) {
this.property1 = property1;
}
public void setProperty2(int property2) {
this.property2 = property2;
}
@Override
public MyComplexObject getObject() throws Exception {
// 在这里可以进行复杂的初始化逻辑
return new MyComplexObject(property1, property2);
}
@Override
public Class<?> getObjectType() {
return MyComplexObject.class;
}
@Override
public boolean isSingleton() {
return true; // 或者 false,根据需要
}
}
<!-- 在 Spring 配置文件中定义 FactoryBean -->
<bean id="myComplexObject" class="com.example.MyComplexObjectFactoryBean">
<property name="property1" value="value1" />
<property name="property2" value="123" />
</bean>
// 在应用程序中获取 MyComplexObject
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyComplexObject myObject = (MyComplexObject) context.getBean("myComplexObject"); // 注意这里是 myComplexObject,而不是 &myComplexObject
System.out.println(myObject.getProperty1()); // 输出: value1
MyComplexObjectFactoryBean factoryBean = (MyComplexObjectFactoryBean) context.getBean("&myComplexObject");
总结:
FactoryBean
是 Spring 框架提供的一种强大的对象创建机制。它通过 getObject()
方法,允许我们在开发过程中自定义对象的创建逻辑,从而实现了更灵活的对象创建和管理。