溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring中 BeanFactory 與 FactoryBean 的區別是什么

發布時間:2021-07-12 10:13:35 來源:億速云 閱讀:194 作者:chen 欄目:編程語言
# 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格式標記

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女