声明: 本博客仅仅是一个初学者的学习记录, 心得总结, 其中肯定有许多错误, 不具有参考价值, 欢迎大佬指正, 谢谢! 想和我交流, 一起学习, 一起进步的朋友可以加我微信 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, 那么对应地需要将换成或将换成
来源: https://www.cnblogs.com/liuhongchen/p/11576346.html