Java 当子类未实现所有构造函数时实例化基类

Java 当子类未实现所有构造函数时实例化基类,java,spring,inversion-of-control,Java,Spring,Inversion Of Control,考虑一个简单的bean: @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class A { public A(Integer a){} public A(String a){} } 拥有一个实例,我可以创建一个实例: beanFactory.getBean(A.class, 1); // using A(Integer) beanFactory.getBean(A.class, "1"); // using

考虑一个简单的bean:

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class A {
    public A(Integer a){}
    public A(String a){}
}
拥有一个实例,我可以创建一个实例:

beanFactory.getBean(A.class, 1); //  using A(Integer)
beanFactory.getBean(A.class, "1"); //  using A(String)
现在,我想要一个子类
a
,它使用提供的两个构造函数之一。我的类层次结构现在变成:

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Primary
public class A {
    public A(Integer a) {}
    public A(String a) {}
}

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class A1 extends A {
    public A1() { super(1); }
}
我希望这些现在能起作用:

beanFactory.getBean(A.class, 1); // using A(Integer)
beanFactory.getBean(A.class, "1"); // using A(String)
beanFactory.getBean(A1.class); // using the A1()
但是,前两个调用失败

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'A1' defined in file [...]: Could not resolve matching constructor 
(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)
请注意,我并没有试图用一些参数创建子类,比如的author

还要注意,如果我定义了(无用的)
A1(整数)
A1(字符串)
构造函数,Spring不再抱怨了

使用弹簧4.2.2.松开

当我定义一些子类时,为什么bean工厂不能用它的构造函数创建基类实例?


请查找复制它的单元测试。

此行为的原因是:Spring不使用构造函数参数来确定要实例化的适当bean类型。(或者,换句话说:它只使用构造函数参数来解析要使用的正确构造函数)

我们只考虑这一行<代码> BeaStudio .GETBeA(A类,1);<代码>

bean解析如下所示:

  • 确定具有请求类型的所有bean。在您的例子中:有两种可能的bean:A或A1(两者都是A类型)

  • 为步骤1中找到的每种可能的类型创建一个实例,并根据给定的参数使用最合适的构造函数。在您的例子中,使用带整数的构造函数实例化一个A和一个A1。(旁注:我们在这里讨论的是原型bean。对于单例bean:当且仅当它不存在时才创建一个新实例)

  • 在步骤2的所有实例化bean中查找@Primary(如果找到,则返回它)

  • 在步骤2中,在所有实例化的bean中查找优先级最高的bean(如果找到,则返回)

  • 抛出“无唯一bean异常”

  • 在您的例子中:当尝试用一个整数参数实例化A1类型的bean时,算法在步骤2失败

    定义
    A1(字符串)
    A1(整数)
    时:算法在步骤2不会失败,因此转到步骤3并解析类型,因为类A上有@Primary

    。请仔细查看第353-->366行,了解此处描述的算法



    我只能猜测这种行为的原因,但可能是因为您可以为构造函数args指定默认值,因此:构造函数args(传递给
    getBean(Class,args…
    )不是消除bean类型歧义的有效线索。

    您没有提供使用的Spring版本。谢谢-我已将此信息添加到问题中。它是4.2.2.RELEASE。了解相关的依赖关系也很好。我正在尝试执行您的测试用例,并且似乎依赖于不止一个spring模块。请检查中的最小示例。因此,对于100个类的类层次结构,它将创建100个实例,只是在最后选择一个?真奇怪。无论如何,谢谢你的解释!对于原型bean:是的(事实上,这不是很有效)。对于单例bean:只创建了一个实例,这当然就是这个实例,它被重用来评估bean是否适合自动连接。(我编辑我的帖子来说明这一点)