溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么

發(fā)布時(shí)間:2021-07-12 10:13:35 來源:億速云 閱讀:142 作者:chen 欄目:編程語言

這篇文章主要講解了“Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么”吧!

 

文章目錄

  • 前言
  • 為什么會(huì)有FactoryBean?
  • 通過源碼深入學(xué)習(xí)FactoryBean
 

前言

常說spring的核心是ioc,ioc的核心是BeanFactory。然而在spring中還有一個(gè)很容易讓人混淆的詞FactoryBean。本文通過一些mybatis源碼來講述其區(qū)別,請(qǐng)大家參考。

 

一、為什么會(huì)有FactoryBean?

BeanFactory是在學(xué)習(xí)IOC第一課的時(shí)候就遇到的。它是生產(chǎn)bean的工廠。在此工廠中,我們可以生產(chǎn)出我們想要的bean,并且通過getBean接口進(jìn)行獲取。

但是在通過getBean獲取bean之前,我們需要事先定義這個(gè)bean漲什么樣子,或者說它由哪些組件組成。定義的方式有很多,可以通過xml進(jìn)行定義,或者在代碼中通過注解(@Bean、@Service)進(jìn)行定義。

就好比一個(gè)Controller,在最原始的xml配置bean的時(shí)候,我們需要定義它是由哪些service組成,然后一點(diǎn)點(diǎn)的配置好。xml要與Controller的service一一對(duì)應(yīng)起來。

Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么  

這種方式的弊端是所有的bean都需要事先定義好,但是有時(shí)候,有的一些bean,我們只知道它大概的樣子,但是無法事先定義出其具體的功能。

就好比,我們知道它是一只鳥,但是不知道是什么種類的鳥,只有在代碼執(zhí)行的時(shí)候,我才知道是什么種類的鳥。如此表達(dá)可能不太直觀,這里可以直接聯(lián)想出mybatis中的mapper。例如UserMapper。

Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么  

在定義UserMapper的時(shí)候,我們知道其最后執(zhí)行的xml的sql語句。而且這樣的mapper又很多,可能還會(huì)有更多的OrderMapper、GoodsMapper等等。如果每一個(gè)都一一定義的話,會(huì)非常的麻煩。但是,我們發(fā)現(xiàn)mapper中的功能都是與數(shù)據(jù)庫交互的代碼。

因此規(guī)范其寫法,通過定義一些標(biāo)準(zhǔn)的寫法,就可以簡(jiǎn)化其定義過程。這樣便出現(xiàn)了@Select注解和@Update注解(還有xml的標(biāo)簽),這樣我們只需要在注解中寫入對(duì)應(yīng)的sql,在代碼執(zhí)行時(shí)候,執(zhí)行對(duì)應(yīng)的sql。

(搜索公眾號(hào)Java知音,回復(fù)“2021”,送你一份Java面試題寶典)

這樣一想可以認(rèn)為是所有的mapper就是鳥,但是不知道它是什么鳥,或者這個(gè)鳥是做什么的(不知道每個(gè)mapper的功能),在真正創(chuàng)建它的時(shí)候,才去關(guān)注它具體的內(nèi)容。

這樣FactoryBean的就有了其意義,它可以定義出一種類型的Bean,并且在創(chuàng)建的時(shí)候再去實(shí)現(xiàn)其具體的功能。里面有三個(gè)方法。

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

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}
   

二、通過源碼深入學(xué)習(xí)FactoryBean

如果還沒有理解FactoryBean。我們可以通過學(xué)習(xí)mybatis源碼,來更加深入的了解FactoryBean。

這里帶領(lǐng)大家了解下Mybatis的MapperFactoryBean,這個(gè)是生成Mapper的FactoryBean。

Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么  

大家可以自行打開源碼查看,通過上圖的流程即可發(fā)現(xiàn)。每一個(gè)mapper是通過MapperFactoryBean的getObject方法進(jìn)行創(chuàng)建,最后生成一個(gè)代理類。在代理類中對(duì)Mapper對(duì)應(yīng)的注解信息進(jìn)行解析。

相信跟一下mybatis的源碼之后,對(duì)FactoryBean會(huì)有更加深入的理解。雖然在開發(fā)時(shí)用FactoryBean的機(jī)會(huì)并不多,但是源碼中會(huì)經(jīng)常遇到,例如spring cloud的feign組件,里面肯定也會(huì)看到FactoryBean的身影。

對(duì)于mybatis和feign,可以很輕松的發(fā)現(xiàn)其共同點(diǎn):

  • 存在一種類型的bean。mybatis是Mapper,feign是FeignClient。
  • 這種bean功能單一。mapper只跟數(shù)據(jù)庫做交互。FeignClient只是接口調(diào)用。

還有我們常用的定時(shí)器框架quartz框架。里面也有JobDetailFactoryBean。Redis中有RedisClientFactoryBean。security框架的UserDetailsManagerResourceFactoryBean。其實(shí)他們都是有一個(gè)共同的特點(diǎn),就是生產(chǎn)的bean是一種類型,在創(chuàng)建的過程中在實(shí)現(xiàn)其功能。到這是不是已經(jīng)理解了FactoryBean呢?

感謝各位的閱讀,以上就是“Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Spring中 BeanFactory 與 FactoryBean 的區(qū)別是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI