1. 程式人生 > >Spring依賴注入的三種方式

Spring依賴注入的三種方式

Spring支援兩種依賴注入方式,分別是屬性注入和建構函式注入。除此之外,Spring還支援工廠方法注入。

1.屬性注入

實體類Car,有三個屬性

public class Car {

    private int maxSpeed;
    private String brand;
    private double price;

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    public
String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; }

bean.xml

<bean id = "car" class
= "com.smart.ditype.Car">
<property name="maxSpeed"><value>200</value></property> <property name="brand"><value>寶馬</value></property> <property name ="price"><value>20000.00</value></property> </bean>

上述程式碼配置了一個Bean,併為Bean的三個屬性提供了屬性值。每一個屬性對應一個標籤,name為屬性名,在Bean實現類中要擁有與其對應的Setter方法。
注意:Spring只會檢查Bean中是否含有Setter方法,至於Bean中是否有對應的屬性成員則不做要求。

2.建構函式注入
建構函式注入是除屬性注入外的另一種常用注入方式,保證一些必要的屬性在Bean例項化時就得到設定,確保Bean在例項化後就可以使用。

(1)按型別匹配入參
Bean必須提供帶參的建構函式

public Car(String brand,double price){
    this.brand = brand;
    this.price = price;
…
<bean id = "car1" class="com.smart.ditype.Car">
        <constructor-arg type = "java.lang.String">
            <value>寶馬</value>
        </constructor-arg>
        <constructor-arg type = "double">
            <value>20000</value>
        </constructor-arg>
</bean>

在的元素中有type屬性,為Spring提供了判斷配置項和建構函式入參對應關係的“資訊”。
注意! 在僅有一個建構函式的情況下,的宣告順序可以用於建構函式的入參順序。但是,Spring的配置檔案採用和元素標籤順序無關的策略,這種順序策略在一定程度上保證配置資訊的準確性。

(2)按索引匹配入參

爪窪通過入參的型別和順序區分不同的過載方法。對於剛剛的配置,有一個String屬性和一個double屬性,但如果有兩個String屬性,因為brand和crop的屬性都是String,所以使用無法確定type指的是哪一個,就需要用到索引匹配入參。

public Car(String brand,String crop,double price){
        this.brand = brand;
        this.crop = crop;
        this.price = price;
    }
<bean id = "car2" class="com.smart.ditype.Car">
        <constructor-arg index = "0" value = "寶馬">
        <constructor-arg index = "1" value = "SDAU">
        <constructor-arg index = "2" value = "20000">

</bean>

建構函式的第一個引數索引為0,第二個是1,以此類推。

(3)聯合使用型別和索引匹配

public Car(String brand,String crop,double price){
        this.brand = brand;
        this.crop = crop;
        this.price = price;
    }
public Car(String brand,String crop,int maxSpeed){
        this.brand = brand;
        this.crop = crop;
        this.maxSpeed = maxSpeed;
    }

這裡Car有兩個建構函式,都有兩個入參,需要聯合使用的type和index才能解決問題。

<bean id = "car3" class="com.smart.ditype.Car">
        <constructor-arg index = "0" type = "java.lang.String">
        <value>寶馬</value>
        </constructor-arg>
        <constructor-arg index = "1" type = "java.lang.String">
        <value>SDAU</value>
        </constructor-arg>
        <constructor-arg index = "2" type = "int">
        <value>200</value>
        </constructor-arg>

</bean>

這個Bean的配置對應(String brand,String crop,int maxSpeed)建構函式。
如果只通過index進行配置,Spring無法確定第三個入參的配置項是int的maxSpeed還是double的price。因此需要明確制定第三個入參的型別就可以消除歧義。所以第一個和第二個中的type可以去掉。

(4)通過自身型別反射匹配入參
(5)迴圈依賴
這倆我也不會,暫時沒用到過。用到了再學。。233

3.工廠方法注入

工廠方法在大二學過,是非常常用的設計模式,也是控制反轉和單例模式的主要實現方法。SpringIoc容器以框架的方式提供工廠方法的功能。

(1)非靜態工廠
有些工廠方法是非靜態的,必須例項化工廠類後才能呼叫工廠方法。

public class CarFactory {

    public Car createBMW(){
        Car car = new Car();
        car.setBrand("寶馬320");
        return car;
    }
}

工廠類負責建立目標類的例項,對外遮蔽例項化的步驟。

<bean id ="carFactory" class = "com.smart.ditype.CarFactory"/>
<bean id = "car4" factory-bean="carFactory"
                  factory-method="createBMW"/>

因為不是靜態的,所以定義一個工廠類的Bean,再用過factory-bean引用工廠類例項,最後通過factory-method指定對應的工廠類方法。

(2)靜態工廠方法

無須在建立工廠例項的情況下就可以呼叫工廠類方法,因此更容易使用。只需將建立方法改成靜態。

public class CarFactory {

    public static Car createBMW(){
        Car car = new Car();
        car.setBrand("寶馬320");
        return car;
    }
}
<bean id = "car5" class = "com.smart.ditype.CarFactory"
 factory-method="createBMW"

對於三種注入方式,選擇問題根據實際情況,無統一標準。
具體考量參照spring api。