
1.5 DI
视频

set方法注入
在创建对象的过程中,Spring可以依据配置对对象的属性进行设置,这个过程称为依赖注入,也就是DI。下面学习使用set方法注入和构造方法注入两种方式。
1.5.1 set方法注入
通常的javabean属性都会私有化,而对外暴露setXxx()和getXxx()方法,此时Spring可以通过setXxx()方法将属性的值注入对象。
set方法注入注意事项:
•如果没有提供set方法,那么就会报错。
•如果添加了新的类属性,那么需要再提供set、get方法和toString方法。
下面举例说明。首先创建Spring-day0-demo03项目,然后导入相应的jar包,并新建一个application Context.xml文件。完成准备工作后创建com.daojie.domain包,在该包中创建Hero类,相关代码如下:

第7~12行代码提供6种不同的属性,包括int、String、List、Set、Map和Properties;第13~30行代码通过set方法注入;第31~34行代码生成toString方法。
然后在applicationContext.xml文件中配置<bean>标签,相关代码如下:


以上代码分别为Hero类中定义的6种属性赋值。
最后创建com.daojie.test包,并在该包中创建TestDemo测试类,然后再创建test01方法,相关代码如下:

以上代码在Hero类中添加了toString方法,在test01的代码中直接输出hero即可输出相应属性。执行test01方法,输出结果如图1-42所示。

图1-42 set方法注入输出的结果
输出结果为applicationContext.xml文件中赋值的内容,因此可以使用set方法设定Spring内置的可以直接注入的类。
如果要添加自定义类,也需要提供set和toString方法,下面举例说明。接着上面的案例,首先在com.daojie.domain包中创建Dog和Cat类,在Dog类中添加name,并提供set方法和toString方法,Cat类中不添加任何内容。
Dog类的相关代码如下:

Cat类中代码如下:

接着在Hero类中添加Dog和Cat类,并添加set方法,重新生成toString方法。下面展示添加Dog类、Cat类以及set方法的相关代码。

最后在applicationContext.xml文件中为其赋值,首先需要在xml文件中通过<bean>标签创建Dog和Cat两个对象。因为在Dog类中创建了name,所以直接在Dog的<bean>标签内为name赋值,相关代码如下:

然后为之前6种类赋值的<bean>标签中输入以下代码:

代码中name等号右侧的dog和cat是Hero中自定义类的属性,ref等号右侧的Dog和cat是在applicationContext.xml文件中创建对象的bean。
执行TestDemo测试类中test01方法,输出结果如图1-43所示。

图1-43 自定义类后注入的结果
可以dog等于Dog类型,name等于“旺财”,这是因为在Dog类中重写了toString方法,并且在applicationContext.xml文件中进行配置。另外,cat输出的是Cat类型的对象地址,这是因为给cat的赋值就是对象地址。
1.5.2 自动装配
视频

自动装配
在Spring的set方式实现的注入过程中,支持自动装配机制。所谓自动装配机制,是指根据要设置的javabean属性的名字或类型到Spring中自动寻找对应id或类型的<bean>进行设置,从而省去依次配置的过程,简化了配置。
下面接着上一节的例子说明自动装配的使用,首先在com.daojie.domain包中创建测试的Teacher类,包含Dog和Cat,并且添加set和toString方法。相关代码如下:

接着在applicationContext.xml文件中配置teacher类,相关代码如下:

通过<bean>标签配置teacher类后,如果按照上一节配置的方法,还需要配置Teacher类中的Dog和Cat属性,而这里使用自动装配省去了该部分代码,代码中的autowire="byName"实现了自动装配机制。
byName自动装配的过程是首先在Teacher类中找到属性名称(dog和cat),然后根据属性名称在Spring容器中进行bean id匹配,如果有bean id和类属性名称相同,则匹配成功,将产生的对象赋值给Teacher类中对应的属性。
最后在TestDemo测试类创建test02方法,相关代码如下:

执行test02方法,输出结果如图1-44所示。

图1-44 自动装配输出的结果
从输出结果可见,通过自动装配实现了set方法的注入,而且节省了在xml文件中大量创建对象和赋值的代码。
自动装配有两种方法:byName和byType。byName是根据类属性的名称去Spring容器中进行bean id的匹配。如果有bean id和类属性名称相同,那么就将产生的对象赋值给类属性。byType是根据类属性的类型去Spring容器中进行bean类型的匹配,如果有bean类型和类属性的类型相同,那么就将产生的对象赋值给类属性。
接着上面的案例,可以根据Teacher类中Dog和Cat数据类型在xml文件中匹配Dog和Cat数据类型,匹配成功后,将产生的对象赋值给类中对应的属性。
注意:
自动装配有两种,优先使用byName,因为类型可能有多个,而id的名称一般是唯一的。
如果需要匹配所有的bean,只需要修改applicationContext.xml文件中的自动输入内容即可,修改后代码如下:


将光标定位在第5行代码最右侧的>括号之前,然后按【Enter】键,再输入default-autowire="byName"代码即可。
1.5.3 构造方法注入
视频

构造方法注入
之前介绍了如何使用set方法为对象赋值,另外,也可以通过构造方法传入并设置对象的属性。Spring也可以通过这样的构造方法实现属性的注入。
下面接着上一节的例子说明构造方法注入,首先在com.daojie.domain包中创建Student类,并创建int、String和Dog类型,然后添加构造方法并重写toString方法,相关代码如下:

接着在applicationContext.xml文件中进行配置,相关代码如下:

在代码中,通过<bean>标签配置Student,接着通过构造方法进行赋值。第2行代码中index="0"代码表示为Student类中索引为0的构造方法进行配置,第3行和第4行分别为索引为1和2的构造方法进行配置。在第3行代码中省略了index ="1"代码,因为该代码指定Student类中的name构造方法,与name="name"代码重复。代码中的value是给参数设定的值;name是指定构造方法的参数名称;type是指定构造方法的参数类型;ref是用于指定引用其他bean的值。
在TestDemo测试类中创建test03方法,相关代码如下:

执行test03方法,输出结果如图1-45所示。

图1-45 通过构造方法注入的结果