【问题标题】:Please explain me this (ambiguity) behavior of autowiring through constructor in Spring请解释一下Spring中通过构造函数自动装配的这种(歧义)行为
【发布时间】:2013-07-14 02:31:11
【问题描述】:

我先提供小代码sn-p,再请教。

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
}

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

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

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

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

输出:

调用参数化构造函数

这是正常现象,可以理解

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

现在,我正在添加 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) 中找到

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢您的回答。我可以很容易地理解这种行为,但对其原因感到困惑。
    【解决方案2】:

    我试过上面的例子:

    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
        }
    

    【讨论】:

      猜你喜欢
      • 2012-03-11
      • 1970-01-01
      • 2011-03-08
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 2013-06-23
      • 1970-01-01
      • 2014-09-03
      相关资源
      最近更新 更多