Spring使用靜態工廠方法建立Bean

1. 使用靜態工廠方法建立Beanjava

    使用靜態工廠方法建立Bean實例時,class屬性也必須指定,但此時class屬性並非指定Bean實例的實現類,而是靜態工廠類。由於Spring須要知道是用哪一個工廠來建立Bean實例。另外,還須要使用factory-method來指定靜態工廠方法名,Spring將調用靜態工廠方法(可能包含一組參數),來返回一個Bean實例,一旦得到了指定Bean實例,Spring後面的處理步驟與採用普通方法建立Bean實例則徹底同樣。須要注意的是,當使用靜態工廠方法來建立Bean時,這個factory-method必需要是靜態的。這段闡述聽上去有點暈,話很少說,上代碼:
設計模式

    先定義一個接口,靜態方法產生的將是該接口的實例:
app

public interface Animal {
    public void sayHello();
}

    下面是接口的兩個實現類:ide

public class Cat implements Animal {
    private String msg;
    //依賴注入時必須的setter方法
    public void setMsg(String msg){
        this.msg = msg;
    }
    @Override
    public void sayHello(){
        System.out.println(msg + ",喵~喵~");
    }
}

public class Dog implements Animal {
    private String msg;
    //依賴注入時必須的setter方法
    public void setMsg(String msg){
        this.msg = msg;
    }
    @Override
    public void sayHello(){
        System.out.println(msg + ",旺~旺~");
    }
}

    下面的AnimalFactory工廠中包含了一個getAnimal的靜態方法,該方法將根據傳入的參數決定建立哪一個對象。這是典型的靜態工廠設計模式。
測試

public clas AnimalFactory {
    public static Animal getAnimal(String type){
        if ("cat".equalsIgnoreCase(type)){
            return new Cat();
        } else {
            return new Dog();
        }
    }
}

    若是須要指定Spring使用AnimalFactory來產生Animal對象,則可在Spring配置文件中做以下配置:this

<!-- 配置AnimalFactory的getAnimal方法,使之產生Cat -->
<bean id="cat" class="com.abc.AnimalFactory" factory-method="getAnimal">
    <!-- 配置靜態工廠方法的參數,getAnimal方法將產生Cat類型的對象 -->
    <constructor-arg value="cat" />
    <!-- 經過setter注入的普通屬性 -->
    <property name="msg" value="貓貓" />
</bean>
<!-- 配置AnimalFactory的getAnimal方法,使之產生Dog -->
<bean id="dog" class="com.abc.AnimalFactory" factory-method="getAnimal">
    <!-- 配置靜態工廠方法的參數,getAnimal方法將產生Dog類型的對象 -->
    <constructor-arg value="dog" />
    <!-- 經過setter注入的普通屬性 -->
    <property name="msg" value="狗狗" />
</bean>

    從上面的配置能夠看出:cat和dog兩個Bean配置的class和factory-method徹底相同,這是由於兩個實例都使用同一個靜態工廠類、同一個靜態工廠方法產生獲得的。只是爲這個靜態工廠方法指定的參數不一樣,使用<constructor-arg />元素來爲靜態工廠方法指定參數。
spa

    主程序獲取cat和dog兩個Bean實例的方法不變,一樣只須要調用Spring容器的getBean()便可:
設計

public class Test {
    public static void main(String args[]){
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Animal a1 = context.getBean("cat", Animal.class);
        a1.sayHello();
        Animal a2 = context.getBean("dog", Animal.class);
        a2.sayHello();
    }
}

    輸出結果:code

貓貓,喵~喵~
狗狗,旺~旺~

    使用靜態工廠方法建立實例時必須提供工廠類和產生實例的靜態工廠方法。經過靜態工廠方法建立實例時須要對Spring配置文件作以下改變;
xml

  • class屬性不在是Bean實例的實現類,而是生成Bean實例的靜態工廠類

  • 使用factory-method指定生產Bean實例的靜態工廠方法

  • 若是靜態工廠方法須要參數,使用<constructor-arg />元素爲其配置

    當咱們指定Spring使用靜態工廠方法來建立Bean實例時,Spring將先解析配置文件,並根據配置文件指定的信息,經過反射調用靜態工廠類的靜態工廠方法,並將該靜態工廠方法的返回值做爲Bean實例,在這個過程當中,Spring再也不負責建立Bean實例,Bean實例是由用戶提供的靜態工廠方法提供的。


2. 使用實例工廠方法建立Bean

    實例工廠方法與靜態工廠方法只有一點不一樣:調用靜態工廠方法只須要使用工廠類便可,調用實例工廠方法則必須使用工廠實例。因此在Spring配置上也只有一點區別:配置靜態工廠方法指定靜態工廠類,配置實例工廠方法則指定工廠實例。一樣是上面的例子將AnimalFactory修改成:

public clas AnimalFactory {
    public Animal getAnimal(String type){  //這裏僅僅是去掉了static關鍵字
        if ("cat".equalsIgnoreCase(type)){
            return new Cat();
        } else {
            return new Dog();
        }
    }
}

    Spring文件修改成:

<!-- 先配置工廠類 -->
<bean id="animalFactory" class="com.abc.AnimalFactory" />
<!-- 這裏使用factory-bean指定實例工廠類對象 -->
<bean id="cat" factory-bean="animalFactory" factory-method="getAnimal">
    <!-- 一樣指定factory-method的參數 -->
    <constructor-arg value="cat" />
    <property name="msg" value="貓貓" />
</bean>

<bean id="dog" factory-bean="animalFactory" factory-method="getAnimal">
    <constructor-arg value="dog" />
    <property name="msg" value="狗狗" />
</bean>

    測試類不用修改,輸出結果和上面相同。

相關文章
相關標籤/搜索