请解释一下我在Spring中通过构造函数进行自动装配的这种(模糊性)行为

时间:2013-07-16 03:35:03

标签: java spring dependency-injection inversion-of-control autowired

我首先提供小代码片段,然后我会要求解释。

public class A {
   private String msg;
   private B b;

   public A () {
      System.out.println("No argument constructor is called");
   }

   public A (B b) {
      System.out.println("Parameterized constructor is called");
         this.b = b;
   }

   // getters and setters
}

============================================== < / p>

<bean id="a" class="A" p:msg="hello" autowire="constructor"/>

<bean id="b" class="B"/>

============================================== < / p>

输出:

  

参数化构造函数被称为

这是正常行为&amp;可以理解的

============================================== < / H1>

现在,我正在添加一个类B的新bean定义,如下所示。

<bean id="a" class="A" p:msg="hello" autowire="constructor"/>

<bean id="b" class="B"/>

<bean id="c" class="B"/>

所以,据我所知,由于通过构造函数自动装配在内部使用'byType',因此它将提供有关bean唯一性违规的异常,例如,如果我使用autowire =“byType”,就会出现这种情况。

但奇怪的是,输出如下所示。

输出:

  

没有参数构造函数被调用

========================================

但请注意,如果A类中没有指定默认构造函数,则会发生预期的异常。那么,它是Spring IoC容器的默认行为吗?如果是的话,请详细解释一下。

提前谢谢。

这个问题也可以在LinkedIn(Spring autowiring through constructor ambiguity

中找到

2 个答案:

答案 0 :(得分:1)

  

如果一个类有多个构造函数,其中任何一个都可以通过自动装配来满足,那么Spring将抛出异常,因为它无法决定自动连接哪个bean。

http://www.studytrails.com/frameworks/spring/spring-auto-wire-constructor.jsp

所以这意味着如果你有多个构造函数,spring需要选择一个。弹簧是如此聪明,可以选择它可以接线的那个。所以你只使用B bean它使用带有B参数的构造函数。如果你有两个B bean,它不能使用这个构造函数,因为它不是唯一的B,所以它回退到默认的构造函数。你删除这个构造函数就会得到异常。

答案 1 :(得分:0)

我试过上面的例子:

<强> A.java

package com.constructor;

public class A {

       private String msg;
       private B b;

       public A () {
          System.out.println("No argument constructor is called");
       }

       public A (B b) {
          System.out.println("Parameterized constructor is called");
             this.b = b;
       }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

       // getters and setters
    }