本文主要介绍Spring以配置方式利用构造函数对bean进行注入的方法
构造函数注入
- 假设目前有一个学生类Student定义如下
public class Student {
private int age;
private String name;
private String addr;
private Bag bag; // 自定义类,书包
private List<String> schedules; // 课程表
private Set<String> clothes; // 衣服
private Map<String, Integer> grades; // 成绩
public Student(int age, String name, String addr, Bag bag, List<String> schedules, Set<String> clothes,Map<String, Integer> grades){
this.age = age;
this.addr = addr;
this.bag = bag;
this.schedules = schedules;
this.clothes = clothes;
this.grades = grades;
}
如果我们通过构造函数注入,则不需要set,get等访问器。可以看到,该类的构造函数包含了int
, 2个String
,1个自定义类型Bag
以及3个集合类型
。
- 对应的Spring配置则需要如下bean定义
<bean id="bag" class="com.limingjian.blog.Bag"/>
<bean id="student" class="com.limingjian.blog.Student">
<constructor-arg value="15"/> <!--age-->
<constructor-arg value="XiaoMing"/>
<constructor-arg value="China"/> <!--addr-->
<constructor-arg ref="bag"/>
<constructor-arg>
<list>
<value>yuwen</value>
<value>shuxue</value>
<null/> <!--可以注入null-->
</list>
</constructor-arg>
<constructor-arg>
<set>
<value>校服</value>
<value>运动服</value>
</set>
</constructor-arg>
<constructor-arg>
<map>
<entry key="yuwen" value="95"/>
<entry key="shuxue" value="96"/>
<!--<entry key="qita" value-ref="qitaBeanID"/> 可以通过此形式引用其他ID-->
</map>
</constructor-arg>
</bean>
可以看到,我们并没有对参数进行类型与名称的声明,所以Spring逐个参数进行了匹配,然后正常完成了任务。倘若我将age与addr的bean定义交换会如何呢?
- 错乱的参数顺序
<constructor-arg value="China"/> <!--int age-->
<constructor-arg value="XiaoMing"/>
<constructor-arg value="15"/> <!-- String addr-->
此时我仍然没有声明类型与名称,当运行时,收获了异常constructor parameter 0: Could not convert argument value of type
。可以推测出,Spring是根据类型匹配到了构造函数,然后按照形参的顺序进行注入的。
那么,如果就想不按顺序注入,怎么办呢?
- 指定名称或者下标的注入
<constructor-arg index="2" value="China"/>
<constructor-arg value="XiaoMing"/>
<constructor-arg name="age" value="15"/>
以上代码展示了不采用默认顺序,而是通过指定形参下标或者参数名的形式进行注入。其中,addr
是第2个参数,age
通过名称指定。
- 集合类型的注入
针对集合类型的注入做以下几点说明:
-
<list>
与<set>
标签可以装配类型为java.util.Collection
的任意实现或者Array
,并没有要求Set
类型必须用<set>
注入,实际属性与选择二者标签之一并没有必然的联系。 -
<map>
标签对应java.util.Map
类型,基本类型用value
,自定义类型value-ref
引用bean,指定键时同理。 - 若键值均为
String
类型,则可以考虑用<props>
代替<map>
,其对应了java.util.Properties
类。