当存在多个构造函数时,使用autowire =“constructor”进行依赖注入?

时间:2014-02-20 11:27:02

标签: java spring

我有以下构造函数的文本编辑器类

 public class TextEditor {
       private SpellChecker spellChecker;

       private SpellChecker1 spellChecker1;

       private SpellChecker2 spellChecker2;

     public TextEditor(SpellChecker spellChecker) {
          this.spellChecker = spellChecker;
        }

       public TextEditor(SpellChecker2 spellChecker2) {
              this.spellChecker2 = spellChecker2;
           }

       public TextEditor(SpellChecker spellChecker, SpellChecker1 spellChecker1,SpellChecker2 spellChecker2) {
              this.spellChecker = spellChecker;
              this.spellChecker1 = spellChecker1;
              this.spellChecker2 = spellChecker2;
           }

       public TextEditor(SpellChecker spellChecker, SpellChecker1 spellChecker1) {
              this.spellChecker = spellChecker;
              this.spellChecker1 = spellChecker1;
           }
        }

在春天豆我有

<bean id="textEditor" class="com.TextEditor" autowire="constructor">
</bean>

我观察到的是具有两个参数的构造函数被一致地调用。是随机的吗?不应该  spring throw exception becoz它不知道需要调用哪个构造函数?

2 个答案:

答案 0 :(得分:6)

这是Spring自动构建器的结果。

它做的第一件事就是获取所有bean类的构造函数并对它们进行排序,首先将公共构造函数放入减少的参数,然后再将所有非公共构造函数放入参数数量减少的情况。这些是候选构造函数。

然后迭代这些候选者,试图从BeanFactory生成参数。如果它不能因为bean丢失或出于其他原因,它会跳过候选者。如果它成功找到参数,它会根据许多因素(参数列表长度,参数类型与参数的接近程度等等)为当前候选构造函数提供权重。然后检查前一个候选人的体重,如果一个人比另一个好,则交换他们。

如果在此过程结束时有候选构造函数,Spring将使用它。

如果你说Spring在3 arg构造函数中使用你的2 arg构造函数,那么这意味着你的3 arg构造函数中没有一个类型的bean。

答案 1 :(得分:0)

更准确地说,下面的例子可以帮助你理解,所以我有一个类Employee,它与资格和地址有关系,bean在xml声明中可用。                                     

<bean id="qualification" class="com.Autowiring.constructor.Qualification">
    <property name="highestQualification" value="BTech"/>
    <property name="certifcations" value="SCJP"/>
</bean>

<bean name="address" class="com.Autowiring.constructor.Address">
    <property name="city" value="Bangalore" />
    <property name="zip" value="560054" />
    <property name="building" value="Building One" />
</bean>

我们有4个构造函数,第1个接受两个参数,即Address和Qualification,第2个接受Qualification,第3个构造函数接受Address,然后第4个接受所有从id,name,dob,address和qualified开始的字段。

//构造函数 - 1

public Employee(Address address, Qualification qualification) {
    super();
    System.out.println(1);
    this.address = address;
    this.qualification = qualification;
}

//构造函数 - 2

public Employee(Qualification qualification) {
    super();
    System.out.println(2);
    this.qualification = qualification;
}

//构造函数 - 3

public Employee(Address address) {
    super();
    System.out.println(3);
    this.address = address;
}

//构造函数 - 4

public Employee(int id, String name, Date dob, Address address,
        Qualification qualification) {

    super();
    System.out.println(4);
    this.id = id;
    this.name = name;
    this.dob = dob;
    this.address = address;
    this.qualification = qualification;
}

案例1 :我们假设未声明构造函数1和4,并且我们在employee bean声明中没有构造函数arg。

行为:构造函数3将被调用,因为这是最后一个构造函数声明的,如果我们改变构造函数定义的顺序,即将构造函数2的位置与3交换。

案例2 :我们假设未声明构造函数4,并且我们在employee bean声明中没有构造函数arg。

行为:在这种情况下,将调用构造函数1,因为它可以获得bean声明中可用的类型Qualification和Address,因此这满足构造函数1的匹配参数的条件。 / p>

案例3 :假设我们在员工bean声明中没有构造函数arg。

行为:在这种情况下,也会调用构造函数1,因为它可以获得bean声明中可用的类型Qualification和Address,因此这满足构造函数1的匹配参数的条件,但它无法调用第4个构造函数,因为id,name和dob在bean声明文件中不可用,因此第1个构造函数是最佳匹配构造函数,因为我们在bean声明中提供了Qualification和Address。

案例4 :假设我们在employee bean声明中有构造函数arg,并且所有构造函数都可用。

行为:它将能够调用第4个构造函数,因为bean声明文件中提供了id,name,dob,qualified和address,因此第3个参数将来自构造函数arg和last两个将来自bean本身的声明,因此将调用第4个构造函数匹配的所有参数,因此将调用第4个构造函数。 结论:所以案例和行为表明,在多个构造函数的情况下,spring容器尝试验证所有依赖属性并基于构造函数中可用于创建对象的所有可用属性进行验证,其中最大可能属性可以被初始化。