FactoryBean?BeanFactory方法使用示例詳解講解
一、FactoryBean:用來自定義Bean的創(chuàng)建邏輯
FactoryBean是接口,是為IOC容器中的Bean的實現(xiàn)提供了更加靈活的方式,F(xiàn)actoryBean在IOC容器的基礎(chǔ)上,給Bean的實現(xiàn)加上了一個簡單工廠模式和裝飾模式。一般情況下實例化一個Bean對象:Spring通過反射機制利用bean的class屬性指定實現(xiàn)類實例化Bean;在某些情況下,實例化Bean過程比較復(fù)雜,如果按照傳統(tǒng)的方式,則需要在bean
中提供大量的配置信息。配置方式的靈活性是受限的,這時采用編碼的方式可能會得到一個簡單的方案。
Spring為此提供了一個org.springframework.bean.factory.FactoryBean的工廠類接口,用戶可以通過實現(xiàn)該接口, 然后在getObject()方法中靈活配置,來定制實例化Bean的邏輯。FactoryBean接口對于Spring框架來說占用重要的地位,Spring自身就提供了70多個FactoryBean的實現(xiàn)——(xxxFactoryBean)。它們隱藏了實例化一些復(fù)雜Bean的細節(jié),給上層應(yīng)用帶來了便利。從Spring3.0開始,F(xiàn)actoryBean開始支持泛型,即接口聲明改為FactoryBean的形式。從BeanFactory及其實現(xiàn)類的getBean() 方法中獲取到的Bean對象,實際上是FactoryBean的getObject()方法創(chuàng)建并返回的Bean對象,而不是FactoryBean本身。
public interface FactoryBean<T> { String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType"; @Nullable T getObject() throws Exception; @Nullable Class<?> getObjectType(); default boolean isSingleton() { return true; } }
方法一:getObject():返回Bean對象;
方法二,getObjectType() :返回的Bean對象的類型;
方法三,isSingleton() :是否是單例對象,true是單例,false是非單例;
實現(xiàn)SqlSessionFactoryBean:
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent>
定義TestBean實現(xiàn)FactoryBean接口并實現(xiàn)getObject()和getObjectType()方法,其中在getObject()方法中實例化一個TestBean對象,并對message進行了一些特殊處理(區(qū)別于構(gòu)造方法)。
@Component public class TestBean implements FactoryBean { private String message; public TestBean() { this.message = "通過構(gòu)造方法初始化實例"; } @Override public Object getObject() throws Exception { TestBean testBean = new TestBean(); testBean.message = "通過FactoryBean.getObject()創(chuàng)建實例"; // 這里并不一定要返回TestBean自身的實例,可以是其他任何對象的實例 return testBean; } @Override public Class<?> getObjectType() { return TestBean.class; } public String getMessage() { return message; } }
TestBean測試類:
@RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class FactoryBeanTest { @Autowired private ApplicationContext context; @Test public void test() { TestBean myBean1 = (TestBean) context.getBean("testBean"); System.out.println("myBean1 = " + myBean1.getMessage()); TestBean myBean2 = (TestBean) context.getBean("&testBean"); System.out.println("myBean2 = " + myBean2.getMessage()); System.out.println("myBean1.equals(myBean2) = " + myBean1.equals(myBean2)); } }
輸出結(jié)果:
myBean1 = 通過FactoryBean.getObject()初始化實例
myBean2 = 通過構(gòu)造方法初始化實例
myBean1.equals(myBean2) = false
結(jié)論:
可見當調(diào)用getBean("testBean")時,Spring通過反射機制發(fā)現(xiàn)TestBean實現(xiàn)了FactoryBean接口,這時Spring容器就調(diào)用接口方法TestBean#getObject()方法返回,這時返回的并不是FactoryBean本身,而是FactoryBean#getObject()方法內(nèi)部所返回的對象TestBean,相當于FactoryBean#getObject()代理了getBean() 方法。如果希望獲取TestBean的實例,則需要在使用getBean(beanName)方法時在beanName前顯示的加上 "&"前綴,如getBean("&testBean")。
當通過getBean()方法獲取到一個Bean時,返回的并不是xxxFactoryBean本身,而是其創(chuàng)建的Bean對象; 如果要獲取xxxFactoryBean對象本身,請在參數(shù)前面加一個&符號來獲取,即:getBean(&BeanName)
二、BeanFactory:負責生產(chǎn)和管理bean的一個工廠類頂層接口
BeanFactory是一個負責生產(chǎn)和管理bean的一個工廠類(接口)。在Spring中,BeanFactory是IOC容器的核心接口,它的職責包括:實例化、定位、配置應(yīng)用程序中的對象及建立這些對象間的依賴。我們通過getBean()方法,傳入?yún)?shù)——bean的名稱或者類型,便可以從Spring容器中來獲取bean。
BeanFactory是用于訪問Spring容器的根接口,是從Spring容器中獲取Bean對象的基礎(chǔ)接口,提供了IOC容器最基本的形式,給具體的IOC容器的實現(xiàn)提供了規(guī)范。BeanFactory只是個接口,并不是IOC容器的具體實現(xiàn),Spring容器給出了很多種 BeanFactory的 擴展實現(xiàn),如:DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。
從類圖中可以看出,我們更常用的ApplicationContext就是一個BeanFactory。ApplicationContext接口由BeanFactory接口派生而來,ApplicationContext包含BeanFactory的所有功能,還提供了以下更多的功能:
1、MessageSource, 提供國際化的消息訪問 ;
2、資源訪問,如URL和文件;
3、事件傳播。
相比BeanFactory,通常建議優(yōu)先使用ApplicationContext。
BeanFactory的一些是實現(xiàn),除了ApplicationContext,還有很多,例如:
AbstractBeanFactory
:抽象Bean工廠,絕大部分的實現(xiàn)類,都是繼承于他DefaultListableBeanFactory
:Spring默認的工廠類XmlBeanFactory
:前期使用XML配置用的比較多的時候用的Bean工廠AbstractXmlApplicationContext
:抽象應(yīng)用容器上下文對象ClassPathXmlApplicationContext
:XML解析上下文對象,用戶創(chuàng)建Bean對象我們早期寫Spring的時候用它
三、FactoryBean與BeanFactory區(qū)別
BeanFactory是個Factory,也就是IOC容器或?qū)ο蠊S,F(xiàn)actoryBean是個Bean。 在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)來進行管理的。但對FactoryBean而言,這個Bean不是簡單的Bean,而是一個能生產(chǎn)或者修飾對象生成的工廠Bean,它的實現(xiàn)與設(shè)計模式中的工廠模式和修飾器模式類似。
以上就是FactoryBean BeanFactory方法使用示例詳解講解的詳細內(nèi)容,更多關(guān)于FactoryBean BeanFactory方法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java基于jdbc連接mysql數(shù)據(jù)庫功能實例詳解
這篇文章主要介紹了java基于jdbc連接mysql數(shù)據(jù)庫功能,結(jié)合實例形式詳細分析了jdbc連接mysql數(shù)據(jù)庫的原理、步驟、實現(xiàn)方法及相關(guān)操作技巧,需要的朋友可以參考下2017-10-10java中進制的轉(zhuǎn)換,Byte與16進制的轉(zhuǎn)換方法
下面小編就為大家?guī)硪黄猨ava中進制的轉(zhuǎn)換,Byte與16進制的轉(zhuǎn)換方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11Java中System.setProperty()用法與實際應(yīng)用場景
System.setProperty是Java中用于設(shè)置系統(tǒng)屬性的方法,它允許我們在運行時為Java虛擬機(JVM)或應(yīng)用程序設(shè)置一些全局的系統(tǒng)屬性,下面這篇文章主要給大家介紹了關(guān)于Java中System.setProperty()用法與實際應(yīng)用場景的相關(guān)資料,需要的朋友可以參考下2024-04-04Java結(jié)構(gòu)性設(shè)計模式中的裝飾器模式介紹使用
裝飾器模式又名包裝(Wrapper)模式。裝飾器模式以對客戶端透明的方式拓展對象的功能,是繼承關(guān)系的一種替代方案,本篇文章以虹貓藍兔生動形象的為你帶來詳細講解2022-09-09SpringBoot validator參數(shù)驗證restful自定義錯誤碼響應(yīng)方式
這篇文章主要介紹了SpringBoot validator參數(shù)驗證restful自定義錯誤碼響應(yīng)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10java實現(xiàn)Img與PDF相互轉(zhuǎn)換
這篇文章主要為大家詳細介紹了java實現(xiàn)Img與PDF相互轉(zhuǎn)換的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05