作者:叄滴水
博客: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。
這裏帶領大家瞭解下Mybatis
的MapperFactoryBean
,這個是生成Mapper
的FactoryBean
。
大家可以自行打開源碼查看,通過上圖的流程即可發現,每一個mapper
是通過MapperFactoryBean
的getObject
方法進行創建,最後生成一個代理類。
相信跟一下mybatis
的源碼之後,對FactoryBean
會有更加深入的理解。
雖然在開發時用FactoryBean
的機會並不多,但是源碼中會經常遇到,例如spring cloud
的feign
組件,裏面肯定也會看到FactoryBean
的身影。
對於 mybatis 和 feign,可以很輕鬆的發現其共同點:
- 存在一種類型的bean。
mybatis
是Mapper
,feign
是FeignClient
。 - 這種
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 正式發佈,全新顛覆性版本!
覺得不錯,別忘了隨手點贊+轉發哦!