首頁 > 軟體

Spring Bean屬性注入的兩種方式詳解

2022-06-11 14:03:20

屬性注入概念

Spring 屬性注入(DI依賴注入)有兩種方式:setter注入構造器注入

這個注入的屬性可以是普通屬性(基本資料型別與String等),也可以是一個參照資料型別(主要是物件),或者是一個集合(list、map、set等)

下表是屬性注入bean標籤中常用的元素

元素名稱描述
constructor-arg構造器注入。該元素的 index 屬性指定構造引數的索引(從 0 開始),type 屬性指定構造引數的型別(type也可以不寫,spring會自動識別引數的型別)
propertysetter注入。該元素的 name 屬性用於指定 Bean 類中相應的屬性名(成員變數名) 。
ref<property> 和 <constructor-arg> 的子元索,用於參照指定bean範例,即 <bean> 元素中的 id 或 name 屬性。
value<property> 和 <constractor-arg> 的子元素,用於直接指定常數值。

一、構造器注入

先來介紹下構造器注入:Spring通過呼叫構造方法為成員變數賦值

  • 使用建構函式實現屬性注入大致步驟如下:
  • 在類中新增一個有參構造方法,構造方法內的每一個引數代表一個需要注入的屬性;
  • 在 Spring 的組態檔中定義Bean;
  • 在 <bean> 元素內使用 <constructor-arg> 元素,對建構函式內的屬性進行賦值,Bean 的構造方法內有多少引數,就需要使用多少個 <constructor-arg> 元素。

下面通過範例介紹如何使用構造器注入

範例1

1.建立員工類Employee和部門類Dept,並新增有參構造方法(關鍵!)

/*員工類Employee*/
public class Employee {
    //員工編號
    private String empNo;
    //員工姓名
    private String empName;
    //部門資訊
    private Dept dept;
    //有參構造方法
    public Employee(String empNo, String empName, Dept dept) {
        this.empNo = empNo;
        this.empName = empName;
        this.dept = dept;
    }
    ----省略toString方法------  
}

/*部門類Dept*/
public class Dept {
    //部門編號
    private String deptNo;
    //部門名稱
    private String deptName;
    //有參構造方法
    public Dept(String deptNo, String deptName) {
        this.deptNo = deptNo;
        this.deptName = deptName;
    }
    ----省略toString方法------
}

2.編寫spring組態檔

<!--部門類屬性注入-->
<bean id="dept" class="com.bighorn.pojo.Dept">
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="後端組"/>
</bean>
<!--員工類屬性注入-->
<bean id="employee" class="com.bighorn.pojo.Employee">
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="bighorn"/>
    <constructor-arg index="2" ref="dept"/>
</bean>

3.編寫執行程式

public static void main(String[] args) {
    //獲取IoC容器
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //從容器中獲取物件
    Employee employee = context.getBean("employee", Employee.class);
    System.out.println(employee);
}

結果如下圖

注意點

spring識別有參構造方法的引數的三種形式:

1.以index識別,案例一就是如此

<bean id="dept" class="com.bighorn.pojo.Dept">
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="後端組"/>
</bean>

2.以name識別,如下

<bean id="dept" class="com.bighorn.pojo.Dept">
    <constructor-arg name="deptNo" value="1"/>
    <constructor-arg name="deptName" value="後端組"/>
</bean>

3.以type識別,如下

<bean id="dept" class="com.bighorn.pojo.Dept">
    <constructor-arg type="int" value="1"/>
    <constructor-arg type="java.lang.String" value="後端組"/>
</bean>

三種形式各有各的好處和壞處。
以type識別不適合有多個引數型別相同的情況;以index形式識別,如果引數順序變了又要重改;以name形式識別,如果引數名變了也要重改。總之,都不太利於解耦

二、setter注入

下面來介紹下setter注入:Spring通過呼叫setter方法為成員變數賦值。

【Spring學習筆記(二)】提到過,在 Spring 範例化 Bean 時,IoC 容器會先呼叫預設構造方法範例化 Bean,然後通過反射機制呼叫這個 Bean 的 setXxx() 方法,將屬性值注入到 Bean 中。

使用setter注入實現屬性注入大致步驟如下:

  • 在 類中提供一個預設的無參構造方法(在沒有帶參構造方法的情況下,可省略),併為所有需要注入的屬性提供一個 setter 方法
  • 在 Spring 的 XML 組態檔中定義Bean
  • 使用 <property> 元素對各個屬性進行賦值。

下面通過範例介紹如何使用setter注入方法

範例2

1.建立員工類Employee和部門類Dept,與範例一不同的是,需要新增各個成員變數的setter方法,也需要提供一個無參構造方法

/*員工類Employee*/
public class Employee {
    //員工編號
    private String empNo;
    //員工姓名
    private String empName;
    //部門資訊
    private Dept dept;
    //無參構造方法,在沒有其他帶參構造方法的情況下,可以省略
    public Employee() {
    }   
    //各個屬性的setter方法
    public void setEmpNo(int empNo) {
        this.empNo = empNo;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    ----省略toString方法------  
}

/*部門類Dept*/
public class Dept {
    //部門編號
    private String deptNo;
    //部門名稱
    private String deptName;
    //無參構造方法,在沒有其他帶參構造方法的情況下,可以省略
    public Dept() {
    }
    //各個屬性的setter方法
    public void setDeptNo(int deptNo) {
        this.deptNo = deptNo;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    ----省略toString方法------
}

2.編寫spring組態檔

<!--使用 property 元素完成屬性注入
        name: pojo類中的屬性名稱
        value: 向屬性注入的值 
     -->
<!--部門類屬性注入-->
<bean id="dept" class="com.bighorn.pojo.Dept">
    <property name="deptNo" value="2"/>
    <property name="deptName" value="前端組"/>
</bean>
<!--員工類屬性注入-->
<bean id="employee" class="com.bighorn.pojo.Employee">
    <property name="empNo" value="114514"/>
    <property name="empName" value="lzh"/>
    <property name="dept" ref="dept"/>
</bean>

3.編寫執行程式

public static void main(String[] args) {
    //獲取IoC容器
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //從容器中獲取物件
    Employee employee = context.getBean("employee", Employee.class);
    System.out.println(employee);
}

結果如下圖

三、如何選擇注入方式

如果物件在建立的過程中必須要注入指定的引數,則可以使用構造器注入行,因為使用setter注入有概率不進行注入導致null物件出現

如果物件在建立過程中注入的引數可有可無 ,則可以使用setter注入

常用的是setter注入方式,有必要時可以兩者結合使用

到此這篇關於Spring Bean屬性注入的兩種方式詳解的文章就介紹到這了,更多相關Spring Bean屬性注入內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com