gpt4 book ai didi

java - 当 child 没有实现所有构造函数时实例化基类

转载 作者:行者123 更新时间:2023-11-30 08:42:27 24 4
gpt4 key购买 nike

考虑一个简单的 bean:

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

拥有一个 BeanFactory 的实例我可以创建 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)

请注意,我并没有尝试使用像 this question 的作者这样的参数创建子类.

另请注意,如果我定义(无用的)A1(Integer)A1(String) 构造函数,Spring 不会再提示了。

使用 Spring 4.2.2.RELEASE。

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

请找一个单元测试重现它 in Github repo .

最佳答案

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

让我们只考虑这一行 beanFactory.getBean(A.class, 1);

bean 解析如下:

  1. 确定所有具有请求类型的 bean。在您的情况下:有 2 种可能的 bean:A 或 A1(均为 A 类型)

  2. 为第 1 步中找到的每种可能类型创建一个实例并根据给定参数使用最合适的构造函数。在您的情况下,使用带有 Integer 的构造函数实例化一个 A 和一个 A1。 (旁注:我们在这里讨论的是 prototype beans。对于 singleton beans :当且仅当它不存在时才会创建新实例)

  3. 在第 2 步的所有实例化 bean 中查找 @Primary(如果找到则返回)

  4. 在第 2 步的所有实例化 bean 中寻找优先级最高的 bean(如果找到则返回)

  5. 抛出“没有唯一的 bean 异常”

在您的情况下:当尝试使用一个 Integer 参数实例化 A1 类型的 bean 时,算法在第 2 步失败。

当您定义 A1(String)A1(Integer) 时:算法不会在第 2 步失败,因此转到第 3 步并解析类型,因为A 类上的@Primary。

Source code is here .仔细查看此处描述的算法的第 353 --> 366 行。


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

关于java - 当 child 没有实现所有构造函数时实例化基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34565344/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com