亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring中BeanFactory?FactoryBean和ObjectFactory的三種的區(qū)別

 更新時(shí)間:2023年01月17日 10:16:17   作者:njitzyd  
關(guān)于FactoryBean?和?BeanFactory的對(duì)比文章比較多,但是對(duì)ObjectFactory的描述就比較少,今天我們對(duì)比下這三種的區(qū)別,感興趣的朋友跟隨小編一起看看吧

Spring中BeanFactory FactoryBean和ObjectFactory的三種的區(qū)別

引言

關(guān)于FactoryBean 和 BeanFactory的對(duì)比文章比較多,但是對(duì)ObjectFactory的描述就比較少,今天我們對(duì)比下這三種的區(qū)別。

結(jié)論

BeanFactory就是對(duì)象工廠,Spring的底層容器,用于實(shí)例化和保存對(duì)象。
FactoryBean是一個(gè)工廠對(duì)象,用于實(shí)例化創(chuàng)建過(guò)程比較復(fù)雜的對(duì)象,對(duì)象的創(chuàng)建過(guò)程是由用戶自己控制的。
ObjectFactory是某個(gè)特定的工廠,用于在項(xiàng)目啟動(dòng)時(shí),延遲實(shí)例化對(duì)象,解決循環(huán)依賴問(wèn)題,也就是三級(jí)緩存那里會(huì)用到,以及結(jié)合Scope,靈活方便的實(shí)現(xiàn)是否需要?jiǎng)?chuàng)建對(duì)象。

BeanFactory

Spring最最核心的接口,Bean工廠,從名字上就能看出這是一個(gè)工廠。它是Spring最底層的容器,負(fù)責(zé)實(shí)例化和保存Spring中的Bean。

public interface BeanFactory {

	String FACTORY_BEAN_PREFIX = "&";
	
	Object getBean(String name) throws BeansException;
	
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	
	Object getBean(String name, Object... args) throws BeansException;
	
	<T> T getBean(Class<T> requiredType) throws BeansException;

	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
	
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
	
	boolean containsBean(String name);
	
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	## 方法很多,不再贅述
}

FactoryBean

public interface FactoryBean<T> {

    //返回的對(duì)象實(shí)例
    T getObject() throws Exception;
    //Bean的類型
    Class<?> getObjectType();
    //true是單例,false是非單例  在Spring5.0中此方法利用了JDK1.8的新特性變成了default方法,返回true
    boolean isSingleton();
}

我們觀察到FactoryBean接口有三個(gè)方法。
getObject用來(lái)返回實(shí)例化后的對(duì)象。
getObjectType用來(lái)返回對(duì)象的類型。
isSingleton用來(lái)標(biāo)識(shí)對(duì)象是否為單例的,這里默認(rèn)為true,Spring會(huì)將實(shí)例化后的對(duì)象放入BeanFactory容器中。

從方法上,能推測(cè)出,這個(gè)凡是實(shí)現(xiàn)了FactoryBean接口的類,負(fù)責(zé)返回這個(gè)java類的實(shí)例化對(duì)象。
從設(shè)計(jì)模式的角度來(lái)看這就是典型的工廠方法模式。由一個(gè)特定的工廠來(lái)生產(chǎn)特定的java類的實(shí)例化對(duì)象。

那么這種寫(xiě)法有哪些好處呢?
正常情況下,Spring中在實(shí)例化對(duì)象的時(shí)候,都是由BeanFactory從上下文中獲取BeanDefinition信息,然后通過(guò)反射,調(diào)用這個(gè)java類的構(gòu)造方法進(jìn)行實(shí)例化。而現(xiàn)在這種形式,我們相當(dāng)于將實(shí)例化的功能交給了FactoryBean去實(shí)現(xiàn)。這種方式主要使用在一些比較復(fù)雜的實(shí)例化過(guò)程中,并非簡(jiǎn)單地設(shè)置一些參數(shù)或者設(shè)置的參數(shù)過(guò)多,過(guò)程中可能需要做一些復(fù)雜的解析、判斷和邏輯處理,這個(gè)時(shí)候交由Spring去通過(guò)反射進(jìn)行實(shí)例化可能就不太靈活了,

Spring容器中有兩種Bean,一種是普通的Bean對(duì)象,一種是實(shí)現(xiàn)了FactoryBean的工廠Bean對(duì)象。如果從BeanFactory中g(shù)etBean的時(shí)候,獲取到的Bean對(duì)象是工廠Bean,會(huì)自動(dòng)的調(diào)用它的getObject方法返回真實(shí)實(shí)例化對(duì)象。
如果就是需要獲取FactoryBean對(duì)象,需要在getBean的時(shí)候加上前綴’&'。

Spring自身就對(duì)FactoryBean有70多種實(shí)現(xiàn),比較常見(jiàn)的就是Proxy,Jndi等場(chǎng)景。

AOP中使用的ProxyFactoryBean。
Dubbo中使用的ReferenceBean。
Mybatis中使用的SqlSessionFactoryBean。

FactoryBean的著重于自定義創(chuàng)建對(duì)象過(guò)程,由BeanFactory通過(guò)FactoryBean來(lái)獲取目標(biāo)對(duì)象,而如果是isSingleton返回true的話spring會(huì)利用單例緩存來(lái)緩存通過(guò)FactoryBean創(chuàng)建的對(duì)象。

ObjectFactory

public interface ObjectFactory<T> {

    //返回的對(duì)象實(shí)例
    T getObject() throws BeansException;
}

這用于延遲查找的場(chǎng)景,它就是一個(gè)普通工廠,當(dāng)?shù)玫?ObjectFactory 對(duì)象時(shí),相當(dāng)于 Bean 沒(méi)有被創(chuàng)建,只有當(dāng) getObject() 方法時(shí),才會(huì)觸發(fā) Bean 實(shí)例化等生命周期。

一方面在循環(huán)依賴的時(shí)候,用于延遲初始化,見(jiàn)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中調(diào)用addSingletonFactory方法,會(huì)把ObjectFactory的Lambda表達(dá)式放入三級(jí)緩存。

另一方面,在AbstractBeanFacotry在doGetBean處的使用時(shí),將創(chuàng)建對(duì)象的步驟封裝到ObjectFactory中 交給自定義的Scope來(lái)選擇是否需要?jiǎng)?chuàng)建對(duì)象來(lái)靈活的實(shí)現(xiàn)scope。除此之外ObjectFactory就是一個(gè)普通的接口

簡(jiǎn)單來(lái)說(shuō)就是通過(guò)FactoryBean你可以控制對(duì)象如何創(chuàng)建,而ObjectFactory借助Scope接口自定義scope你可以控制對(duì)象的創(chuàng)建時(shí)機(jī)也可以用來(lái)延遲初始化來(lái)解決循環(huán)依賴問(wèn)題。

參考

BeanFactory和FactoryBean對(duì)比

補(bǔ)充介紹spring中關(guān)于FactoryBean 和 ObjectFactory的認(rèn)識(shí)和區(qū)別

FactoryBean:

這個(gè)接口使你可以提供一個(gè)復(fù)雜的邏輯來(lái)生成 Bean。它本質(zhì)是一個(gè) Bean,但這個(gè) Bean 不是用來(lái)注 入到其它地方像 Service、Dao 一樣使用的,它是用來(lái)生成其它 Bean 使用的。實(shí)現(xiàn)了這個(gè)接口后, Spring 在容器初始化時(shí),把實(shí)現(xiàn)這個(gè)接口的 Bean 取出來(lái),使用接口的 getObject()方法來(lái)生成我們 要想的 Bean。當(dāng)然,那些生成 Bean 的業(yè)務(wù)邏輯也要寫(xiě) getObject()方法中。 其返回的對(duì)象不是指定類的一個(gè)實(shí)例,其返回的是該工廠 Bean 的 getObject 方法所返回的對(duì)象。創(chuàng) 建出來(lái)的對(duì)象是否屬于單例由 isSingleton 中的返回決定。

使用場(chǎng)景:

1、通過(guò)外部對(duì)類是否是單例進(jìn)行控制,該類自己無(wú)法感知
2、在創(chuàng)建 Object 對(duì)象之前進(jìn) 行初始化的操作,在 afterPropertiesSet()中完成。(一次性的初始化,保存在成員變量中,并不是 每次 getObject 都會(huì)調(diào)用 afterPropertiesSet,afterPropertiesSet 只會(huì)被調(diào)用一次)

ObjectFactory:

它的目的也是作為一個(gè)工廠,來(lái)生成 Object(這個(gè)接口只有一個(gè)方法 getObject())。這個(gè)接口一般被 用來(lái),包裝一個(gè) factory,通過(guò)個(gè)這工廠來(lái)返回一個(gè)新實(shí)例(prototype 類型)。這個(gè)接口和 FactoryBean 有點(diǎn)像,但 FactoryBean 的實(shí)現(xiàn)是被當(dāng)做一個(gè) SPI(Service Provider Interface)實(shí)例來(lái)使用在 BeanFactory 里面;ObjectFactory 的實(shí)現(xiàn)一般被用來(lái)注入到其它 Bean 中,作為 API 來(lái)使用。就像ObjectFactoryCreatingFactoryBean 的 例 子 , 它 的 返 回 值 就 是 一 個(gè) ObjectFactory , 這 個(gè) ObjectFactory 被注入到了 Bean 中,在 Bean 通過(guò)這個(gè)接口的實(shí)例,來(lái)取得我們想要的 Bean。

總的來(lái)說(shuō),F(xiàn)actoryBean 和 ObjectFactory 都是用來(lái)取得 Bean,但使用的方法和地方不同, FactoryBean 被配置好后,Spring 調(diào)用 getObject()方法來(lái)取得 Bean,ObjectFactory 配置好后, 在 Bean 里面可以取得 ObjectFactory 實(shí)例,需要我們手動(dòng)來(lái)調(diào)用 getObject()來(lái)取得 Bean。

到此這篇關(guān)于Spring中BeanFactory FactoryBean和ObjectFactory的三種的區(qū)別的文章就介紹到這了,更多相關(guān)BeanFactory FactoryBean和ObjectFactory區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論