Spring的依赖注入 DI

依赖注入(DI)和控制反转(IoC)是从不同的角度描述的同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦

依赖注入方式:
1、构造方法注入
2、setter方法注入
3、接口注入
4、复杂类型(集合)注入

代码

//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(不推荐,不常用):

<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(推荐写法,但不常用):

<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;
}

​ 注入:

<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.接口注入(没用,不说了)

4.集合注入
​注意:下文中的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,那么对应地需要将换成或将换成

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