Spring Bean屬性註入的兩種方式詳解
屬性註入概念
Spring 屬性註入(DI依賴註入)有兩種方式:setter註入,構造器註入。
這個註入的屬性可以是普通屬性(基本數據類型與String等),也可以是一個引用數據類型(主要是對象),或者是一個集合(list、map、set等)
下表是屬性註入bean標簽中常用的元素
元素名稱 | 描述 |
---|---|
constructor-arg | 構造器註入。該元素的 index 屬性指定構造參數的索引(從 0 開始),type 屬性指定構造參數的類型(type也可以不寫,spring會自動識別參數的類型) |
property | setter註入。該元素的 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屬性註入內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 詳解Spring Bean的集合註入和自動裝配
- 一文搞懂Spring Bean中的作用域和生命周期
- Spring框架的JdbcTemplate使用
- Spring IOC中的Bean對象用法
- Mybatis-Plus多表關聯查詢的使用案例解析