在Spring中有兩種類型的bean,一種是普通Bean,一種是工廠Bean,即FactoryBean。FactoryBean跟普通bean不同,其返回的對象不是指定類的一個實例,而是該FactoryBean的getObject方法所返回的對象。創建出的對象是否屬於單例由isSingleton中的返回決定。
1. 爲什麼使用FactoryBean
一般情況下,Spring通過反射機制,利用<bean>中的class屬性指定的實現類實例化Bean。在某些情況下,實例化Bean過程比較複雜,如果按照傳統的方式,需要在<bean>中提供大量的配置信息。配置方法的靈活性受限,這時採用編碼方式可能會得到一個簡單的方案。Spring爲此提供了一個org.springframework.bean.factory.FactoryBean工廠類接口,用戶可以通過實現該接口定製實例化Bean的邏輯。可以隱藏實例化一些複雜Bean的細節。給上層應用帶來便利。
從Spring3.0開始,FactoryBean開始支持泛型,即接口聲明改爲FactoryBean<T>的形式。
以Bean結尾,表示他是一個Bean,不同於其他bean的是:它實現了FactoryBean<T>的接口。該Bean的ID實際上是從BeanFactory中獲取的實際的getObject()返回的對象,而不是FactoryBean本身。如果要獲取FactoryBean對象,可以在id前面加一個&符號來獲取。
2. FactoryBean是什麼
package org.springframework.beans.factory;
public interface FactoryBean<T> {
//返回由FactoryBean創建bean的實例,如果是單例模式(isSingleton=true)
//則該實例會放在Spring容器單例的緩存池中。
T getObject() throws Exception;
//返回FactoryBean創建的Bean實例
Class<?> getObjectType();
//返回由FactoryBean創建的實例是單例還是多例的
boolean isSingleton();
}
當配置文件中<Bean>的class屬性配置的實現類是FactoryBean時,通過getBean()方法返回的實際上是getObject的對象。
3. FactoryBean怎麼用
FactoryBean通常是用來創建比較複雜的Bean,一般的bean使用XML配置即可,但若是一個Bean的創建過程中涉及到很多其他Bean 和 複雜的邏輯,使用XML配置比較複雜的話,這時可以考慮使用FactoryBean。
@Component
public class MyFactoryBean implements FactoryBean<List<String>>, InitializingBean, DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(MyFactoryBean.class);
private String params = "";
private List<String> list;
//InitializingBean實現方法
public void afterPropertiesSet() throws Exception {
//屬性注入完後,調用該方法,該方法可以實現“業務”邏輯。創建出List<String>集合
String[] split = params.split(",");
list = Arrays.asList(split);
}
public List<String> getObject() throws Exception {
return list;
}
public Class<?> getObjectType() {
return List.class;
}
public boolean isSingleton() {
return true;
}
//[dɪˈspəʊzəbl](對象銷燬的時候會調用 蒂斯跑則報)DisposableBean 接口的實現方法
public void destroy() throws Exception {
logger.debug("對象銷燬...");
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
<bean id="myList" class="com.springmvc.common.aspect.MyFactoryBean">
<property name="params" value="1,2,3,4"/>
</bean>
總結
將對象交由Spring管理的方式:
- 使用XML配置文件<bean>標籤;
- 在自定義類上使用@Component註解(將自定義對象交由Spring管理)
- 使用FactoryBean<T>靈活的創建出對象,然後使用XML或者@Component註解交由Spring管理。
- 使用@Bean註解(靈活的創建對象,並放入Spring容器中);
注:本質上Spring的IOC(控制反轉),包含兩步,一是創建出bean,二是將其放入到容器中。
1. xml配置文件的方式,是Spring通過反射機制創建對象,再放入到容器中。對於我們來說,我們發揮的空間不大,必須按照特定的規則注入屬性。面對繁雜的對象,或者可靈活(依賴數據庫,實時查詢)配置的對象,便有些無力了。而FactoryBean<T>可以解決複雜對象創建。通過代碼的方式,創建出bean對象(實際上是通過new的方式),然後在通過@Component或者XML配置放入到容器中。
2. @Bean註解,不僅可以在代碼中我們手動的創建出bean對象(new),而且可以注入到容器中,可以說是一種更加方便的解決方案!
文章參考