欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

引言

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

結論

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

BeanFactory

Spring最最核心的接口,Bean工廠,從名字上就能看出這是一個工廠。它是Spring最底層的容器,負責實例化和保存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> {

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

我們觀察到FactoryBean接口有三個方法。
getObject用來返回實例化后的對象。
getObjectType用來返回對象的類型。
isSingleton用來標識對象是否為單例的,這里默認為true,Spring會將實例化后的對象放入BeanFactory容器中。

從方法上,能推測出,這個凡是實現(xiàn)了FactoryBean接口的類,負責返回這個java類的實例化對象。
從設計模式的角度來看這就是典型的工廠方法模式。由一個特定的工廠來生產(chǎn)特定的java類的實例化對象。

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

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

Spring自身就對FactoryBean有70多種實現(xiàn),比較常見的就是Proxy,Jndi等場景。

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

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

ObjectFactory

public interface ObjectFactory<T> {

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

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

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

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

簡單來說就是通過FactoryBean你可以控制對象如何創(chuàng)建,而ObjectFactory借助Scope接口自定義scope你可以控制對象的創(chuàng)建時機也可以用來延遲初始化來解決循環(huán)依賴問題。

參考

BeanFactory和FactoryBean對比

補充介紹spring中關于FactoryBean 和 ObjectFactory的認識和區(qū)別

FactoryBean:

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

使用場景:

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

ObjectFactory:

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

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

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

相關文章

最新評論