自动装配 Spring 超类

问题描述 投票:0回答:4

为什么Spring在自动装配时自动选择超类类型?

例如,如果我有

@Component
public class Foo {}

@Component
public class Bar extends Foo {}

有人自动接线

@Autowired
private Foo foo;

Spring 为什么总是选择超类型

Foo
?这不应该是一个“ambiguously”映射(并导致 Spring 抛出错误)吗?

从技术上讲,您没有两个

Foo
候选人吗? (例如,当从 Foo 中删除 @Component 时,Bar 会被自动选取...)

java spring inheritance javabeans autowired
4个回答
9
投票

这可能是因为自动装配是通过名称而不是类型完成的。如果我像这样使用 xml 设置我的 bean:

<bean id="foo1" class="Foo"/>
<bean id="foo2" class="Bar"/>

并尝试按类型自动装配:

@Autowired private Foo aFoo;

我明白了

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [Foo]

3
投票

自动装配可以使用类型和 bean 名称来工作,具体取决于您的配置方式。

在本例中,由于有两个类型为

Foo
的 bean,因此可以选择
Foo
实例,因为它与变量
foo
的名称匹配。

如果将

foo
重命名为其他名称会发生什么?


3
投票

如果有两个相同类型的bean,那么spring会尝试通过您指定的变量名称来解决依赖关系。如果名称与任何 bean 名称不匹配,则会抛出错误。但是,如果它找到与您指定的变量名称匹配的 bean 名称,它将注入该 bean。 因此,在注入依赖项时,spring 会同时考虑类型和名称。


0
投票

另一个原因是因为 Foo 类没有用 @ConditionalOnMissingBean(Foo.class) 注解。此注释可确保如果上下文中存在另一个 Foo 类型的 bean(即 Bar),则不会创建 Foo 类的实例。

© www.soinside.com 2019 - 2024. All rights reserved.