文章目录
概要
使用场景
MyBatis:在Spring与MyBatis整合时,通常会使用SqlSessionFactoryBean来创建SqlSessionFactory实例。SqlSessionFactoryBean实现了FactoryBean接口,使得Spring能够管理MyBatis的会话工厂。
Hibernate:类似地,Spring也可以通过实现FactoryBean接口的Bean来管理Hibernate的SessionFactory。
区别
1、定义与角色:
- BeanFactory:是Spring IoC容器的核心接口,用于管理Bean的一个工厂。它定义了IoC容器的最基本形式,并提供了IoC容器应遵守的最基本的接口,也就是Spring IoC所遵守的最底层和最基本的编程规范。
- BeanFactory的主要职责包括实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
FactoryBean:是一个特殊的Bean,它实现了FactoryBean接口。FactoryBean不仅仅是一个Bean,它更像是一个工厂,用于生成或修饰其他Bean的实例。通过实现FactoryBean接口,可以自定义Bean的创建过程,隐藏复杂Bean实例化的细节。
2、功能与用途:
- BeanFactory:
作为IoC容器的核心接口,BeanFactory提供了管理和访问容器中Bean对象的基本方法,如getBean()、containsBean()等。它是Spring IoC容器的基础,定义了容器的基本行为。 - FactoryBean:
主要用于创建复杂或特殊的Bean实例。通过实现getObject()方法,FactoryBean可以动态地创建Bean实例,并返回给Spring容器。这种方式增加了Bean实例化的灵活性,使得在Spring配置文件中无需详细描述复杂Bean的创建过程。
3、返回对象:
当通过BeanFactory的getBean()方法获取Bean时,如果Bean是普通Bean,则直接返回该Bean的实例。如果Bean是FactoryBean的实现,则默认返回的是FactoryBean.getObject()方法返回的对象,而不是FactoryBean本身。如果希望获取FactoryBean实例本身,需要在Bean名称前加上&符号。
联系
- 共同目标:BeanFactory和FactoryBean都服务于Spring的IoC容器,旨在简化和管理应用程序中的对象依赖关系。
- 依赖关系:FactoryBean作为Bean的一种,其生命周期和创建过程也受到BeanFactory的管理。FactoryBean的实现可以依赖于BeanFactory提供的功能,以便在创建Bean实例时利用容器的特性。
使用场景
- BeanFactory:
- 适用于需要直接管理和访问IoC容器中Bean对象的场景。
- 作为Spring IoC容器的核心接口,BeanFactory在Spring框架的底层实现中扮演着重要角色。
- FactoryBean:
- 适用于需要自定义Bean创建过程的场景,特别是当Bean的创建逻辑较为复杂或需要动态生成Bean实例时。
- FactoryBean常用于集成第三方库或框架到Spring中,通过实现FactoryBean接口来封装第三方库或框架的初始化过程,使得这些库或框架的Bean能够由Spring容器统一管理。
FactoryBean使用
一、FactoryBean接口定义
从Spring 3.0开始,FactoryBean接口开始支持泛型,接口声明改为FactoryBean的形式。该接口主要包含三个方法:
- getObject():返回由FactoryBean创建的Bean实例。如果isSingleton()返回true,则该实例会被放入Spring容器的单例池中。
- getObjectType():返回FactoryBean创建的Bean类型。这允许在不需要实例化对象的情况下检查特定类型的Bean,例如在自动装配时。
- isSingleton():返回由FactoryBean创建的Bean实例的作用域是否为单例(Singleton)。从Spring 5.0开始,此方法有了默认值true,表示默认创建单例Bean。
二、FactoryBean的使用步骤
- 定义POJO类:首先定义一个普通的Java类,作为FactoryBean将要创建的Bean类型。
- 实现FactoryBean接口:创建一个类实现FactoryBean接口,并重写上述三个方法。在getObject()方法中,编写创建Bean实例的逻辑;在getObjectType()方法中,返回创建的Bean的类型;isSingleton()方法可以根据需要重写,以改变Bean的作用域。
- 配置Spring容器:在Spring的配置文件(XML或注解方式)中,将FactoryBean的实现类配置为一个Bean。当Spring容器启动时,会自动识别FactoryBean,并通过调用其getObject()方法来获取实际的Bean实例。
- 获取Bean实例:通过Spring容器的getBean()方法获取Bean实例时,如果Bean的class属性配置的是FactoryBean的实现类,则默认返回的是FactoryBean调用getObject()方法返回的对象,而不是FactoryBean本身。如果希望获取FactoryBean实例本身,需要在Bean名称前加上&符号。
三、FactoryBean的使用场景
- 创建复杂对象:当Bean的创建过程比较复杂,且不适合在XML配置文件中直接描述时,可以使用FactoryBean来封装创建逻辑。
- 集成第三方库:在集成第三方库时,如果第三方库提供的Bean不符合Spring的要求,可以通过实现FactoryBean接口来封装第三方库的Bean,使其能够被Spring容器管理。
- 动态代理:FactoryBean可以用于创建动态代理对象,从而在运行时动态地改变对象的行为。
四、示例
以下是一个简单的FactoryBean示例,用于创建一个User对象:
public class UserFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
// 创建User对象,并设置其属性
User user = new User();
user.setName("张三");
user.setAge(30);
return user;
}
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
public boolean isSingleton() {
// 默认返回true,表示创建的Bean是单例的
return true;
}
}
在Spring配置文件中配置该FactoryBean:
<bean id="userFactoryBean" class="com.example.UserFactoryBean"/>
然后,可以通过getBean(“userFactoryBean”)来获取User对象,但实际上获取的是UserFactoryBean.getObject()方法返回的对象。如果希望获取UserFactoryBean实例本身,应使用getBean(“&userFactoryBean”)。
总结
BeanFactory和FactoryBean在Spring框架中各自扮演着不同的角色。BeanFactory作为IoC容器的核心接口,定义了容器的基本行为和功能;而FactoryBean则提供了一种自定义Bean创建过程的机制,增加了Bean实例化的灵活性和复杂性。在实际开发中,根据具体需求选择合适的机制来管理和创建Bean实例是非常重要的。