Spring中 BeanFactory 与 FactoryBean 的区别是什么

发布时间:2021-07-12 10:13:35 作者:chen
来源:亿速云 阅读:189
# Spring中 BeanFactory 与 FactoryBean 的区别是什么

## 前言

在Spring框架的核心容器模块中,`BeanFactory`和`FactoryBean`是两个名称相似但功能完全不同的接口,初学者很容易混淆。本文将深入剖析二者的设计理念、使用场景和底层实现,通过源码解析和实际案例演示它们的本质区别。

---

## 一、基础概念解析

### 1.1 BeanFactory:Spring的IoC基础容器

**定义**:
`org.springframework.beans.factory.BeanFactory`是Spring框架最基础的IoC容器接口,提供了DI(依赖注入)的核心能力。

**核心特征**:
- 基础容器功能(Bean的实例化、依赖注入)
- 延迟加载机制(默认行为)
- 支持多种Bean作用域(Singleton/Prototype等)

```java
public interface BeanFactory {
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType);
    // 其他方法...
}

1.2 FactoryBean:特殊的对象工厂

定义org.springframework.beans.factory.FactoryBean是一个用于创建复杂对象的工厂接口,本身也是一个由Spring管理的Bean。

核心特征: - 生产对象的工厂模式实现 - 可以返回任意类型的对象实例 - 支持单例/原型模式控制

public interface FactoryBean<T> {
    T getObject() throws Exception;
    Class<?> getObjectType();
    boolean isSingleton();
}

二、架构层级对比

2.1 在Spring体系中的位置

维度 BeanFactory FactoryBean
接口层级 顶级核心接口(容器本身) 扩展接口(特殊的Bean类型)
实现类示例 DefaultListableBeanFactory SqlSessionFactoryBean
注册方式 容器根接口 作为普通Bean注册到容器中

2.2 UML关系图

@startuml
interface BeanFactory
interface FactoryBean

class DefaultListableBeanFactory {
    + getBean()
}
class MyFactoryBean {
    + getObject()
    + getObjectType()
}

BeanFactory <|-- DefaultListableBeanFactory
FactoryBean <|.. MyFactoryBean
DefaultListableBeanFactory --> FactoryBean : 包含
@enduml

三、核心区别详解

3.1 设计目的差异

BeanFactory: - 作为容器角色管理所有Bean的生命周期 - 提供基础的依赖查找(DL)能力 - 构成整个框架的基础设施

FactoryBean: - 作为工厂角色创建特定类型的复杂对象 - 隐藏对象创建的复杂细节 - 通常用于集成第三方库(如MyBatis的SqlSessionFactory)

3.2 使用方式对比

BeanFactory典型用法

// 获取容器实例
BeanFactory factory = new XmlBeanFactory(
    new ClassPathResource("applicationContext.xml"));
// 获取普通Bean
MyService service = factory.getBean(MyService.class);

FactoryBean典型用法

<!-- 配置FactoryBean -->
<bean id="toolFactory" class="com.example.ToolFactoryBean">
    <property name="factoryId" value="9090"/>
</bean>
// 获取FactoryBean产品对象
Tool tool = context.getBean("toolFactory"); // 返回的是getObject()结果
// 获取FactoryBean本身
ToolFactoryBean factory = context.getBean("&toolFactory"); // 注意&前缀

3.3 源码实现分析

BeanFactory核心逻辑(以DefaultListableBeanFactory为例):

public Object getBean(String name) throws BeansException {
    // 处理Bean别名
    String beanName = transformedBeanName(name);
    
    // 尝试从缓存获取单例
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null) {
        return getObjectForBeanInstance(...);
    }
    
    // 创建新实例
    Object beanInstance = createBean(beanName, mbd, args);
    return getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}

FactoryBean处理逻辑

protected Object getObjectForBeanInstance(
    Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    
    // 处理&前缀请求
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }
    
    // 处理FactoryBean产品对象
    if (beanInstance instanceof FactoryBean) {
        return getObjectFromFactoryBean((FactoryBean<?>) beanInstance, name, !synthetic);
    }
    
    return beanInstance;
}

四、典型应用场景

4.1 BeanFactory适用场景

  1. 框架扩展开发:需要直接操作底层容器时
  2. 资源受限环境:移动端等需要轻量级容器的场景
  3. 特殊加载需求:需要精细控制Bean初始化顺序时

4.2 FactoryBean经典实现

实现类 作用 所属框架
SqlSessionFactoryBean 创建MyBatis的SqlSessionFactory MyBatis-Spring
ProxyFactoryBean 创建AOP代理对象 Spring AOP
JndiObjectFactoryBean 获取JNDI资源 Spring核心

自定义FactoryBean示例

public class TimerFactoryBean implements FactoryBean<StopWatch> {
    @Override
    public StopWatch getObject() {
        return new StopWatch("Custom Timer");
    }
    
    @Override
    public Class<?> getObjectType() {
        return StopWatch.class;
    }
    
    @Override
    public boolean isSingleton() {
        return true;
    }
}

五、常见误区辨析

5.1 容易混淆的点

  1. 名称相似性:两者都包含”Bean”和”Factory”关键词
  2. 获取方式:未理解&前缀的特殊含义
  3. 作用误解:认为FactoryBean是BeanFactory的子接口

5.2 典型错误案例

错误代码

// 错误地期望获取FactoryBean实例
MyFactoryBean factory = context.getBean("myFactoryBean");
// 实际上应该使用:
MyFactoryBean factory = context.getBean("&myFactoryBean");

错误配置

<!-- 错误地将普通Bean当作FactoryBean使用 -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
      factory-method="getConnection"/> <!-- 这不是FactoryBean! -->

六、扩展知识

6.1 相关设计模式

  1. BeanFactory:体现了容器模式(Container Pattern)
  2. FactoryBean:实现了工厂方法模式(Factory Method Pattern)

6.2 Spring官方文档说明

“A FactoryBean is a bean that is itself a factory for creating other beans.” —— Spring Framework Reference Documentation


总结对比表

对比维度 BeanFactory FactoryBean
本质 IoC容器基础接口 特殊Bean类型
创建目标 管理所有Bean 创建特定复杂对象
获取方式 直接作为容器使用 通过&前缀获取工厂本身
典型实现 DefaultListableBeanFactory SqlSessionFactoryBean
设计模式 容器模式 工厂方法模式
使用频率 框架底层使用多 业务开发使用多

结语

理解BeanFactoryFactoryBean的区别,关键在于把握: 1. 角色认知:前者是容器,后者是特殊的生产者 2. 设计意图:前者提供基础设施,后者解决复杂实例化问题 3. 使用场景:根据实际需求选择合适的技术方案

掌握这一区别将帮助开发者更深入地理解Spring框架的设计哲学,在复杂系统集成和框架扩展时做出更合理的技术决策。 “`

注:本文实际约2400字,包含: - 6个主要章节 - 3个代码示例 - 2个图表(表格+UML) - 5个重点标注段落 - 完整的Markdown格式标记

推荐阅读:
  1. BeanFactory和FactoryBean在Spring中的区别是什么
  2. BeanFactory与FactoryBean在Spring中有什么不同

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring beanfactory factorybean

上一篇:php中怎么实现传值赋值和传地址赋值

下一篇:php中抽象类如何使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》