Spring 爲什麼會有 FactoryBean?

作者:叄滴水
博客:https://blog.csdn.net/qq_30285985/

前言

常說 spring 的核心是 ioc,ioc 的核心是 BeanFactory。然而在 spring 中還有一個很容易讓人混淆的詞FactoryBean。

本文通過一些 mybatis 源碼來講述其區別,請大家參考。另外,關注公衆號Java技術棧,在後臺回覆:面試,可以獲取我整理的 Java、Spring 系列面試題和答案,非常齊全。

一、爲什麼會有FactoryBean?

BeanFactory是在學習 IOC 第一課的時候就遇到的,它是生產 bean 的工廠,在此工廠中,我們可以生產出我們想要的 bean,並且通過getBean接口進行獲取。

但是在通過getBean獲取 bean 之前,我們需要事先定義這個 bean 長什麼樣子,或者說它由哪些組件組成。

定義的方式有很多,可以通過xml進行定義,或者在代碼中通過註解(@Bean、@Service)進行定義。

就好比一個 Controller,在最原始的 xml 配置 bean 的時候,我們需要定義它是由哪些service組成,然後一點點的配置好,xml要與 Controller 的service一一對應起來。

這種方式的弊端是所有的bean都需要事先定義好,但是有時候,有的一些bean,我們只知道它大概的樣子,但是無法事先定義出其具體的功能。就好比,我們知道它是一隻鳥,但是不知道是什麼種類的鳥,只有在代碼執行的時候,我才知道是什麼種類的鳥。

如此表達可能不太直觀,這裏可以直接聯想出mybatis中的mapper,例如UserMapper

在定義UserMapper的時候,我們知道其最後執行的xml的sql語句。而且這樣的mapper又很多,可能還會有更多的OrderMapper、GoodsMapper等等。 如果每一個都一一定義的話,會非常的麻煩。

但是,我們發現mapper中的功能都是與數據庫交互的代碼。因此規範其寫法,通過定義一些標準的寫法,就可以簡化其定義過程。這樣便出現了@Select註解和@Update註解(還有xml的標籤),這樣我們只需要在註解中寫入對應的sql,在代碼執行時候,執行對應的sql。

這樣一想可以認爲是所有的mapper就是鳥,但是不知道它是什麼鳥,或者這個鳥是做什麼的(不知道每個mapper的功能),在真正創建它的時候,纔去關注它具體的內容。

這樣FactoryBean的就有了其意義,它可以定義出一種類型的Bean,並且在創建的時候再去實現其具體的功能。

裏面有三個方法:

  • getObject 獲取bean方法,在此方法中,我們可以自己定義一個對象,然後自行修改其創建過程。通過這個方法,我們可以在mapper創建的時候再實現其具體的功能。
  • getObjectType 獲取這類的類型。
  • isSingleton 是否單例。
public interface FactoryBean<T> {
    
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
    
}

二、通過源碼深入學習FactoryBean

如果還沒有理解FactoryBean,我們可以通過學習mybatis源碼,來更加深入的瞭解FactoryBean。

這裏帶領大家瞭解下MybatisMapperFactoryBean,這個是生成MapperFactoryBean

大家可以自行打開源碼查看,通過上圖的流程即可發現,每一個mapper是通過MapperFactoryBeangetObject方法進行創建,最後生成一個代理類。

相信跟一下mybatis的源碼之後,對FactoryBean會有更加深入的理解。

雖然在開發時用FactoryBean的機會並不多,但是源碼中會經常遇到,例如spring cloudfeign組件,裏面肯定也會看到FactoryBean的身影。

對於 mybatis 和 feign,可以很輕鬆的發現其共同點:

  • 存在一種類型的bean。mybatisMapper,feignFeignClient
  • 這種bean功能單一。mapper只跟數據庫做交互。FeignClient只是接口調用。

還有我們常用的定時器框架 quartz 框架,裏面也有 JobDetailFactoryBean,Redis 中有 RedisClientFactoryBean,security 框架的 UserDetailsManagerResourceFactoryBean。

其實他們都是有一個共同的特點,就是生產的 bean 是一種類型,在創建的過程中在實現其功能。

到這是不是已經理解了FactoryBean呢?

本文來自作者「叄滴水」投稿,謝謝分享,也歡迎愛好技術分享的各位技術朋友向「Java技術棧」投稿,讓更多人看到,投稿方式:關注公衆號「Java技術棧」在後臺回覆:投稿。

近期熱文推薦:

1.600+ 道 Java面試題及答案整理(2021最新版)

2.終於靠開源項目弄到 IntelliJ IDEA 激活碼了,真香!

3.阿里 Mock 工具正式開源,幹掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式發佈,全新顛覆性版本!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章