Spring——依賴注入(DI)詳解


聲明:本博客僅僅是一個初學者的學習記錄、心得總結,其中肯定有許多錯誤,不具有參考價值,歡迎大佬指正,謝謝!想和我交流、一起學習、一起進步的朋友可以加我微信Liu__66666666

這是簡單學習一遍之后的記錄,后期還會修改。

一、概念引入

​ 我們通過前文Spring——IOC已經知道怎么創建一個空白的實例對象,但是這個實例對象是沒有進行任何成員變量設置的,都是默認值,例如int類型默認為0、引用類型默認為null。

​ 那我們如果想創建帶有特定屬性的對象,那現在有個Computer類,他有屬性”型號“。所以出廠的時候這個屬性就是早被設定好了,那代碼中的工廠如何去設置這個屬性呢?其實依賴注入(DI,Dependency Injection)所做的工作就是為Spring中的Bean設置屬性(成員變量的值)。

​ 百度百科概念:所謂依賴注入,是指程序運行過程中,如果需要調用另一個對象協助時,無須在代碼中創建被調用者,而是依賴於外部的注入。Spring的依賴注入對調用者和被調用者幾乎沒有任何要求,完全支持對POJO之間依賴關系的管理。

二、依賴注入方式

​ 依賴注入常見的有三種:

	- 通過構造方法注入
	- setter方法注入
	- 接口注入

​ 現在有蘋果電腦公司的“MacBook pro 2019”型號的電腦都是“macOS Mojave”系統,那該怎么設置型號和操作系統這兩個屬性呢?下面我們就以這個電腦為例探討一下!

​ 首先建好項目並導入jar包,創建好applicationContext.xml文件,操作步驟參考Spring——IOC

​ 項目目錄結構如下:

​ Computer類:

public class Computer {

    private String type;//電腦型號
    private OperatingSystem operatingSystem;//操作系統
		
    public Computer() {}
    public Computer(String type, OperatingSystem operatingSystem) {
        this.type = type;
        this.operatingSystem = operatingSystem;
    }
//此處略去getter setter toString方法
}

​ OperatingSystem類(這是Computer的一個屬性:操作系統)

public class OperatingSystem {
    private String name;//操作系統名字,例如Windows、macOS
  
  //操作系統版本,例如,當name為Windows,version為10的時候,就是win10
    private String version;

  	public OperatingSystem(){}
    public OperatingSystem(String name, String version) {
        this.name = name;
        this.version = version;
    }
//此處略去getter setter toString方法

}

1.構造方法注入(一定要寫對應的構造方法!)

​ 此方式使用的是bean標簽內部的 標簽進行依賴注入。

​ 以如下構造方法為例

public Computer(String type, OperatingSystem operatingSystem) {
    this.type = type;
    this.operatingSystem = operatingSystem;
}
  • 寫法1(不推薦,不常用):
<!--macOS mojave-->
<bean id="operatingSystem" class="di.OperatingSystem">
    <constructor-arg index="0" value="macOS"/>
    <constructor-arg index="1" value="Mojave"/>
</bean>

<bean id="computer" class="di.Computer">
    <constructor-arg index="0" value="MacBook Pro 2019"/>
    <constructor-arg index="1" ref="operatingSystem"/>
</bean>

標簽的寫法還是和之前一樣,唯一不同的是有了標簽體,標簽體內部就是用來進行屬性設置(依賴注入)的。

​ 每個constructor-arg標簽代表構造方法中的一個參數;

​ 屬性index代表參數的順序,從0開始,index=“0”代表的是構造方法的String type這個參數,index=“1”代表的是OperatingSystem這個參數;

​ 屬性value代表的是這個參數要傳入的值,例如type這個參數對應的是macOS,version是Mojave,一般來說,基本類型和String類型要用value屬性來傳值。

​ 由於在Computer類中我們引用了OperatingSystem這個對象,所以需要先定義好OperatingSystem這個bean,以供我們將其注入到computer這個bean中,其實OperatingSystem就是Computer的一個依賴。而在第二個bean中,有一個ref屬性,這個用來傳value傳不了的值,ref在本例中的值為operatingSystem這個bean的id。

  • 寫法2(推薦寫法,但不常用):
<!--macOS mojave-->
<bean id="operatingSystem" class="di.OperatingSystem">
    <constructor-arg name="name" value="macOS"/>
    <constructor-arg name="version" value="Mojave"/>
</bean>

<bean id="computer" class="di.Computer">
    <constructor-arg name="type" value="MacBook Pro 2019"/>
    <constructor-arg name="operatingSystem" ref="operatingSystem"/>
</bean>

​ 其他地方與寫法1一樣,唯一區別就是將寫法1中的index屬性換成了name屬性,這樣直接通過參數名來確定,清晰明了,不容易出錯。

2.setter方法注入(一定要寫好空參構造和所有屬性的setter方法!!!)

​ 此方式使用的是bean標簽內部的 屬性進行依賴注入。

​ 以如下構造方法為例

public Computer(String type, OperatingSystem operatingSystem) {
    this.type = type;
    this.operatingSystem = operatingSystem;
}

​ 注入:

<!--macOS mojave-->
<bean id="operatingSystem" class="di.OperatingSystem">
    <property name="name" value="macOS"/>
    <property name="version" value="Mojave"/>
</bean>

<bean id="computer" class="di.Computer">
    <property name="type" value="MacBook Pro 2019"/>
    <property name="operatingSystem" ref="operatingSystem"/>
</bean>

​ 其實與構造函數注入的第二種方式差不多,只不過是把 換成了

3.接口注入(沒用,不說了)

三、集合注入

注意:下文中的value標簽,當需要設的值是自己定義的bean時,要用 標簽替換。

​ 為Computer類新增屬性keys,表示鍵盤上的鍵的集合。

1.數組與List(可互相替換)

​ 其實Spring中將Array和List等同起來了。

​ 寫法1(constructor-arg + array):

<bean id="computer" class="di.Computer">
    <constructor-arg name="keys">
        <array>
            <value>a</value>
            <value>b</value>
            <value>c</value>
        </array>
    </constructor-arg>
</bean>

​ 寫法2(constructor-arg + list):

<bean id="computer" class="di.Computer">
    <constructor-arg name="keys">
            <list>
                <value>a</value>
                <value>b</value>
            </list>
    </constructor-arg>
</bean>

​ 寫法3(property + array):

<bean id="computer" class="di.Computer">
    <property name="keys">
            <array>
                <value>a</value>
                <value>b</value>
            </array>
    </property>
</bean>

​ 寫法4(property + list):

<bean id="computer" class="di.Computer">
    <property name="keys">
            <list>
                <value>a</value>
                <value>b</value>
            </list>
    </property>
</bean>

2.Set

​ 寫法1(constructor-arg):

<bean id="computer" class="di.Computer">
    <constructor-arg name="keys">
            <set>
                <value>a</value>
                <value>b</value>
            </set>
    </constructor-arg>
</bean>

​ 寫法2(property):

<bean id="computer" class="di.Computer">
    <property name="keys">
            <set>
                <value>a</value>
                <value>b</value>
            </set>
    </property>
</bean>

3.Map

​ 為Computer類新增屬性map<String,String> sofewares,key表示軟件,value表示軟件安裝目錄

​ 為Computer類新增屬性map<String,Singer> songs,key表示歌曲名,value表示歌手對象

​ 寫法1(property):

<bean id="singerEdSheeran" class="di.Singer">
    <property name="name" value="Ed Sheeran"/>
</bean>

<bean id="computer" class="di.Computer">
    <property name="softwares">
            <map>
                <entry key="WeChat" value="/Users/...."/>
                <entry key="Intellij Idea" value="/usr/local/...."/>
            </map>
    </property>
    <property name="songs">
        <map>
            <entry key="Shape of You" value-ref="singerEdSheeran"/>
            <entry key="I dont care" value-ref="singerEdSheeran"/>
        </map>
    </property>
</bean>

​ 寫法2(將寫法1的property換成constructor-arg即可)

​ 注意,如果key或value要引用其他bean,那么對應地需要將 換成 或將 換成


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM