【问题标题】:Spring 3 constructor injection anomaly: documentation vs. realitySpring 3 构造函数注入异常:文档与现实
【发布时间】:2014-07-02 20:51:49
【问题描述】:

事实

Spring 3.2 文档 (http://docs.spring.io/spring/docs/3.2.9.RELEASE/spring-framework-reference/htmlsingle/#beans-constructor-injection):

当引用另一个 bean 时,类型是已知的,并且可以进行匹配(就像前面的示例一样)。当使用简单类型时,比如true,Spring无法判断该值的类型,因此无法在没有帮助的情况下按类型匹配。

package examples;

public class ExampleBean {

    // No. of years to the calculate the Ultimate Answer
    private int years;

    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

在上述场景中,如果您使用 type 属性显式指定构造函数参数的类型,则容器可以使用简单类型的类型匹配。例如:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>

我的班级:

package client;

public class Client {

    private int id;
    private String name;

    public Client(int id, String name, String email) {
        super();
        this.id = id;
        this.name = name;
    }

}

bean 定义:

<bean id="someClient" class="client.Client">
    <constructor-arg value="5"></constructor-arg>
    <constructor-arg value="5"></constructor-arg>
    <constructor-arg value="5"></constructor-arg>
</bean>

问题

我预计 Spring IoC 容器将无法创建 bean someClient,因为如上所述,它应该无法处理指定的构造函数参数类型。但是,再一次,根据早先的文档:

如果 bean 定义的构造函数参数中不存在潜在的歧义,则在 bean 定义中定义构造函数参数的顺序是在实例化 bean 时将这些参数提供给适当构造函数的顺序.

但可惜的是,Spring 毫不费力地注册了 someClient bean。这对我来说似乎很矛盾。

问题

那么根据 Spring 的说法,什么是模棱两可的情况?上面的例子显然不是模棱两可的,Spring 很乐意按照 bean 定义中定义的顺序提供参数。什么时候在 bean 定义中使用 name/index 属性真的有用?

【问题讨论】:

  • 首先要尝试的是添加一个新的构造函数。没有歧义,因为您的示例中只有一个选项。
  • 确实,有一个 (int, String) 和一个 (String, String) 构造函数会导致它失败并出现 BeanCreationException。如果您能提供完整的答案,我会接受它作为最佳答案!

标签: spring dependency-injection ioc-container spring-3 constructor-injection


【解决方案1】:

考虑一下

<constructor-arg value="5"></constructor-arg>

您尚未指定类型,但 5 可以轻松转换为 String 或任何数字类型。同样,作为一个例子,

<constructor-arg value="java.lang.String"></constructor-arg>

Spring 可以生成 StringClass 对象作为参数。如果每个类型都有一个构造函数,那么就会有歧义。如果仅存在一个构造函数,则将使用 那个 构造函数的适当转换策略。

如果只有一个构造函数,就没有歧义了。

【讨论】:

    【解决方案2】:

    混淆 Spring 的意义何在?我的独特解释是测试或研究。

    但对于现实生活,如果您在三个月后看到相同的代码。我相信您将无法弄清楚您要做什么,不清楚并且无法阅读您自己的代码。

    避免使事情复杂化。您可以使用 index 属性和 name 属性。我曾经和第二个一起工作。

    现在,一个强烈的建议,改用注释。

    认为您可以共享您的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 2020-02-23
      • 1970-01-01
      相关资源
      最近更新 更多