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。