Spring框架——使用構造函數或set實現的依賴注入

Spring 中的依賴注入

​ 依賴注入:Dependency Injection,它是 spring 框架核心 ioc 的具體實現

​ 我們的程序在編寫時,通過控制反轉,把對象的創建交給了 spring,但是代碼中不可能出現沒有依賴的情況,ioc 解耦只是降低他們的依賴關係,但不會消除

​ 例如:我們的業務層仍會調用持久層的方法,那這種業務層和持久層的依賴關係,在使用 spring 之後,就讓 spring 來維護了,簡單的說,就是坐等框架把持久層對象傳入業務層,而不用我們自己去獲取

通過構造函數實現依賴注入

​ 顧名思義,就是使用類中的構造函數,給成員變量賦值,賦值的操作不是我們自己做的,而是通過配置的方式,讓 Spring 框架來爲我們注入的,下面我們來看具體代碼:

​ AccountServiceImpl 類中存在着StringIntegerDate三種類型的變量。分別代表基本類型及 String其他特殊類型兩大類,並提供他們的構造函數:

package com.lmh.service.impl;

import com.lmh.dao.IAccountDao;
import com.lmh.dao.impl.AccountDaoImpl;
import com.lmh.service.IAccountService;

import java.util.Date;

/**
 * 賬戶的業務層實現類
 */
public class AccountServiceImpl implements IAccountService {

    private String name;
    private Integer age;
    private Date birthday;

    public AccountServiceImpl(String name, Integer age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    @Override
    public void saveAccount() {
        System.out.println("save service");
        System.out.println(name + ", " + age + ", " + birthday);
    }

}

​ 在bean.xml中配置依賴注入:

<bean id="now" class="java.util.Date"/>
<bean id="accountService" class="com.lmh.service.impl.AccountServiceImpl">
    <constructor-arg name="name" value="test"/>
    <constructor-arg name="age" value="18"/>
    <constructor-arg name="birthday" ref="now"/>
</bean>

​ 這裏需要注意,由於Date是其他特殊類型,不被包含在 Java 的基本類型或字符串中,所以我們需要爲Date類型創建一個<bean>,然後在另一個<bean><constructor-arg>標籤中使用ref屬性來引用它,實現依賴注入

​ 這裏我是使用<constructor-arg>標籤的name屬性來指定變量名實現依賴注入的,<constructor-arg>標籤還支持使用typeindex兩個屬性,其中type是根據變量類型爲變量賦值,這裏存在使用的侷限性,index通過變量在構造函數參數列表中的位置(從 0 開始)來爲變量賦值,可以看到,使用name還是比較實用的

​ 而value標籤是爲基本類型變量直接賦值,它可以將" "中的值自動轉換爲相應的數據類型,ref是專門爲特殊的類型進行賦值的,它通過引用定義好的<bean>來進行賦值

優缺點

​ 優勢:在獲取 bean 對象時,注入數據是必須的操作,否則對象無法創建成功

​ 弊端:改變了 bean 對象的實例化方式,在我們創建對象時,如果用不到這些數據,也必須提供

通過 Set 方法實現依賴注入

​ 該方法我們需要在類中爲變量添加對應的 set 方法:

package com.lmh.service.impl;

import com.lmh.service.IAccountService;

import java.util.Date;

/**
 * 賬戶的業務層實現類
 */
public class AccountServiceImpl2 implements IAccountService {

    // 如果是經常變化的數據,並不適用於注入的方式
    private String name;
    private Integer age;
    private Date birthday;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public void saveAccount() {
        System.out.println("save service");
        System.out.println(name + ", " + age + ", " + birthday);
    }

}

​ 在bean.xml中配置依賴注入:

<bean id="accountService2" class="com.lmh.service.impl.AccountServiceImpl2">
    <property name="name" value="test"/>
    <property name="age" value="21"/>
    <property name="birthday" ref="now"/>
</bean>

​ 使用 set 方法實現依賴注入時,我們使用<bean>標籤內部的<property>標籤,<property>標籤的使用以及內部的屬性和<constructor-arg>標籤相同,對於Date這種類型,同樣需要使用引用的方式進行賦值

優缺點

​ 優勢:創建對象時沒有明確的限制,可以直接使用默認構造函數

​ 弊端:如果有某個成員必須有值,則獲取對象時有可能 set 方法沒有執行

集合類型變量的依賴注入

​ 集合類型的變量如何實現依賴注入呢?我們這裏以 set 方法爲例

package com.lmh.service.impl;

import com.lmh.service.IAccountService;

import java.util.*;

/**
 * 賬戶的業務層實現類
 */
public class AccountServiceImpl3 implements IAccountService {

    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String, String> myMap;
    private Properties myProps;

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

    @Override
    public void saveAccount() {
        System.out.println("save service");
        System.out.println(Arrays.toString(myStrs));
        System.out.println(myList);
        System.out.println(mySet);
        System.out.println(myMap);
        System.out.println(myProps);
    }

}

​ 在bean.xml中配置依賴注入:

<bean id="accountService3" class="com.lmh.service.impl.AccountServiceImpl3">
    <property name="myStrs">
        <array>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
            <value>DDD</value>
        </array>
    </property>
    <property name="myList">
        <list>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
            <value>DDD</value>
        </list>
    </property>
    <property name="mySet">
        <set>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
            <value>AAA</value>
        </set>
    </property>
    <property name="myMap">
        <map>
            <entry key="testA" value="aaa"/>
            <entry key="testB" value="bbb"/>
        </map>
    </property>
    <property name="myProps">
        <props>
            <prop key="testc">ccc</prop>
            <prop key="testd">ddd</prop>
        </props>
    </property>
</bean>

​ 以上是集合類型變量使用 set 方法實現依賴注入的代碼,這裏需要注意一點,相同類型的集合可以使用相同的標籤實現依賴注入,即array、List、Set屬於同類型,Map、Properties屬於同類型,例如array可以通過<list>標籤實現依賴注入

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章