Spring利用构造函数注入

本文主要介绍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通过名称指定。

  • 集合类型的注入
    针对集合类型的注入做以下几点说明:
  1. <list><set>标签可以装配类型为java.util.Collection的任意实现或者Array,并没有要求Set类型必须用<set>注入,实际属性与选择二者标签之一并没有必然的联系。
  2. <map>标签对应java.util.Map类型,基本类型用value,自定义类型value-ref引用bean,指定键时同理。
  3. 若键值均为String类型,则可以考虑用<props>代替<map>,其对应了java.util.Properties类。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容