在Spring框架中,FactoryBean是一个重要的接口,用于简化复杂对象的创建过程。与普通Bean不同,当我们在Spring容器中配置一个FactoryBean
类型的Bean时,实际获取的对象并不是该FactoryBean
本身,而是其getObject()
方法返回的对象。这种机制使得Spring能够隐藏复杂组件的创建细节,为开发者提供简洁的使用接口。
典型应用场景:在整合第三方框架时,如MyBatis的SqlSessionFactory
创建,Spring正是通过FactoryBean
机制来实现的。
核心方法解析
FactoryBean
接口定义如下:
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() { return true; }
}
-
getObject()
返回由FactoryBean
创建的对象实例。此方法决定了我们实际从容器中获取的对象。 -
getObjectType()
返回创建对象的类型。Spring在容器初始化阶段会调用此方法来确定Bean的类型。 -
isSingleton()
指示对象是否是单例。默认返回true
,即默认创建单例对象。若需原型模式,可重写返回false
。
示例:自定义FactoryBean
1. 创建User类
public class User {
private String name;
// 省略构造方法、Getter/Setter等
}
2. 实现UserFactoryBean
public class UserFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
return new User(); // 返回User实例
}
@Override
public Class<?> getObjectType() {
return User.class; // 指定对象类型为User
}
}
3. 配置XML
<bean id="user" class="com.example.UserFactoryBean"/>
4. 测试代码
@Test
public void testUserFactoryBean() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) ctx.getBean("user"); // 实际获取的是User对象
System.out.println(user); // 输出User实例
}
注意:若需获取FactoryBean
本身而非其创建的对象,可在Bean的ID前添加&
符号:
UserFactoryBean factory = (UserFactoryBean) ctx.getBean("&user");
原理解析
-
与普通Bean的区别
普通Bean在容器中以其实际类型存在,而FactoryBean
是一种特殊Bean,充当对象创建的工厂。容器会调用其getObject()
方法返回目标对象。 -
Bean生命周期
Spring仅管理FactoryBean
实例的生命周期,不管理其创建的对象。若需自定义销毁逻辑,可让FactoryBean
实现DisposableBean
接口。 -
延迟加载
结合SmartFactoryBean
接口,可实现更精细的控制(如延迟初始化)。
常见问题
1. FactoryBean与BeanFactory的区别?
-
BeanFactory:Spring容器的基础接口,负责管理所有Bean。
-
FactoryBean:用于创建特定对象的工厂Bean,属于被管理的Bean之一。
2. 如何判断Bean是否是FactoryBean?
通过BeanFactory
的isFactoryBean(String name)
方法判断。若返回true
,则该Bean为FactoryBean
。
总结
FactoryBean
是Spring中用于封装复杂对象创建逻辑的核心机制。通过实现FactoryBean
接口,开发者能够将对象的创建过程与使用解耦,提升代码的可维护性。在整合第三方库或需要精细控制对象创建时,FactoryBean
是一个强有力的工具。
关键点:
-
通过
getObject()
返回实际对象。 -
使用
&
前缀获取FactoryBean
实例。 -
默认单例,可通过重写
isSingleton()
改变。