- BeanFactory
表示它是一個(gè)工廠類(接口), 它負(fù)責(zé)生產(chǎn)和管理bean的一個(gè)工廠。在Spring中,BeanFactory是IOC容 器的核心接口,它的職責(zé)包括:實(shí)例化蔑鹦、定位、配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴箕宙。
BeanFactory只是個(gè)接口举反,并不是IOC容器的具體實(shí)現(xiàn),但是Spring容器給出了多種實(shí)現(xiàn)扒吁,如 DefaultListableBeanFactory火鼻、XmlBeanFactory、ApplicationContext等雕崩,XmlBeanFactory就是常用的一個(gè)魁索,該實(shí)現(xiàn)將以XML方式描述組成應(yīng)用的對(duì)象及對(duì)象間的依賴關(guān)系。XmlBeanFactory類將持有此XML配置元數(shù)據(jù)盼铁,并用它來構(gòu)建一個(gè)完全可配置的系統(tǒng)或應(yīng)用粗蔚。
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&"; //FactoryBean解引用符,getBean時(shí)加上獲取FactoryBean實(shí)例
Object getBean(String name) throws BeansException; //根據(jù)名稱獲取Bean
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
boolean containsBean(String name); //容器是否包含該名稱的Bean
boolean isSingleton(String name) throws NoSuchBeanDefinitionException; //是否為單例
boolean isPrototype(String name) throws NoSuchBeanDefinitionException; //是否為多例
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; //查詢指定了名字的Bean的Class類型是否是特定的Class類型饶火。這個(gè)Class類型可以由用戶來指定鹏控。
Class<?> getType(String name) throws NoSuchBeanDefinitionException; //查詢指定名字的Bean的 Class類型
String[] getAliases(String name); //獲取別名, 這些別名都是用戶在BeanDefinition中定義的。
}
- FactoryBean
一般情況下肤寝,Spring通過反射機(jī)制利用<bean>的class屬性指定實(shí)現(xiàn)類實(shí)例化Bean当辐,在某些情況下,實(shí)例化Bean過程比較復(fù)雜鲤看,如果按照傳統(tǒng)的方式缘揪,則需要在<bean>中提供大量的配置信息。配置方式的靈活性是受限的义桂,這時(shí)采用編碼的方式可能會(huì)得到一個(gè)簡單的方案找筝。
Spring為此提供了一個(gè)org.springframework.bean.factory.FactoryBean的工廠類接口,用戶可以通過實(shí)現(xiàn)該接口定制實(shí)例化Bean的邏輯慷吊。 FactoryBean接口對(duì)于Spring框架來說占用重要的地位袖裕,Spring自身就提供了70多個(gè)FactoryBean的實(shí)現(xiàn)。它們隱藏了實(shí)例化一些復(fù)雜Bean的細(xì)節(jié)溉瓶,
給上層應(yīng)用帶來了便利急鳄。從Spring3.0開始谤民,F(xiàn)actoryBean開始支持泛型,即接口聲明改為FactoryBean<T>的形式攒岛。
package org.springframework.beans.factory;
public interface FactoryBean<T> {
T getObject() throws Exception; //返回實(shí)例化Bean對(duì)象
Class<?> getObjectType(); //返回實(shí)例化Bean的類型
boolean isSingleton(); //Bean是否為單例, 為true赖临,則該實(shí)例會(huì)放到Spring容器中單實(shí)例緩存池中胞锰。
}
- FactoryBean 使用舉例
定義一個(gè)Car實(shí)體,包含最大速度灾锯、品牌、價(jià)格等屬性嗅榕,如果使用傳統(tǒng)方式配置下面Car的<bean>時(shí)顺饮,Car的每個(gè)屬性分別對(duì)應(yīng)一個(gè)<property>元素標(biāo)簽。
public class Car {
private int maxSpeed ;
private String brand ;
private double price ;
//get/set方法
}
? 可以通過FactoryBean以分隔符的形式一次性指定所有屬性值
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo ;
public Car getObject () throws Exception {
Car car = new Car () ;
String [] infos = carInfo .split ( "," ) ;
car.setBrand ( infos [ 0 ]) ;
car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;
car.setPrice ( Double. valueOf ( infos [ 2 ])) ;
return car;
}
public Class<Car> getObjectType () {
return Car.class ;
}
public boolean isSingleton () {
return false ;
}
public String getCarInfo () {
return this.carInfo ;
}
// 接受逗號(hào)分割符設(shè)置屬性信息
public void setCarInfo ( String carInfo ) {
this.carInfocarInfo = carInfo;
}
}
? XML配置
<bean id="car" class="com.test.factorybean.CarFactoryBean" carInfo="超級(jí)跑車,400,2000000"/>
當(dāng)調(diào)用getBean("car") 時(shí)凌那,Spring通過反射機(jī)制發(fā)現(xiàn)CarFactoryBean實(shí)現(xiàn)了FactoryBean的接口兼雄,這時(shí)Spring 容器就調(diào)用接口方法CarFactoryBean的getObject()方法返回。如果希望獲取CarFactoryBean的實(shí)例帽蝶,則需要在使用getBean(beanName) 方法時(shí)在beanName前顯示的加上 "&" 前綴赦肋,例如getBean("&car")。
- BeanFactory和FactoryBean的區(qū)別
BeanFactory和FactoryBean其實(shí)沒有什么比較的励稳,只是兩者的名稱特別接近佃乘,BeanFactory是提供了IOC容器最基本的形式,給具體的IOC容器的實(shí)現(xiàn)提供了規(guī)范驹尼。FactoryBean可以 說為IOC容器中Bean的實(shí)現(xiàn)提供了更加靈活的方式趣避,F(xiàn)actoryBean在IOC容器的基礎(chǔ)上給Bean的實(shí)現(xiàn)加上了一個(gè)簡單工廠模式和裝飾模式,我們可以在getObject()方法中靈活配置新翎。其實(shí)在Spring源碼中有很多FactoryBean的實(shí)現(xiàn)類程帕,要想深入準(zhǔn)確的理解FactoryBean,只有去讀讀Spring源碼了。
參考鏈接