FactoryBean(創建複雜的Bean)

在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管理的方式:

  1. 使用XML配置文件<bean>標籤;
  2. 在自定義類上使用@Component註解(將自定義對象交由Spring管理)
  3. 使用FactoryBean<T>靈活的創建出對象,然後使用XML或者@Component註解交由Spring管理。
  4. 使用@Bean註解(靈活的創建對象,並放入Spring容器中);

注:本質上Spring的IOC(控制反轉),包含兩步,一是創建出bean,二是將其放入到容器中。
1. xml配置文件的方式,是Spring通過反射機制創建對象,再放入到容器中。對於我們來說,我們發揮的空間不大,必須按照特定的規則注入屬性。面對繁雜的對象,或者可靈活(依賴數據庫,實時查詢)配置的對象,便有些無力了。而FactoryBean<T>可以解決複雜對象創建。通過代碼的方式,創建出bean對象(實際上是通過new的方式),然後在通過@Component或者XML配置放入到容器中。
2. @Bean註解,不僅可以在代碼中我們手動的創建出bean對象(new),而且可以注入到容器中,可以說是一種更加方便的解決方案!

文章參考

FactoryBean的作用

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章