我试图理解为什么Spring bean的依赖关系解析与自动装配的工作方式不同。
鉴于我们有两个A和B类,其中B扩展A:
public class A {}
public class B {} extends A {}
遵循Java配置:
@Configuration
public class TestConfiguration {
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B();
}
@Bean
public A testBean(A bean) {
return bean;
}
}
产生此错误:
Description:
Parameter 0 of method testBean in com.so.demo.TestConfiguration required a single bean, but 2 were found:
- a: defined by method 'a' in class path resource [com/so/demo/TestConfiguration.class]
- b: defined by method 'b' in class path resource [com/so/demo/TestConfiguration.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
错误的假设(见下文引用):
但是如果我从配置中删除 testBean 并尝试自动装配类型为A的bean:
@SpringBootApplication
public class DemoApplication implements ApplicationRunner {
@Autowired
A a;
@Override
public void run(ApplicationArguments arg0) throws Exception {
System.out.println(a.getClass().getName());
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
autowired字段的类型是正确的A.另外,如果我从配置中删除一个bean并只留下B bean,那么B bean将自动连接到字段DemoApplication #a。在这种情况下,我期望的是这种行为。
现在我的问题是,为什么自动装配正确地推断出类型(使用精确类型而不是子类),即使有两个可能的候选者(一个是子类)?但是在配置中注入依赖性会导致上述错误。
感谢@Sotirios Delimanolis澄清这一部分:
所以我的假设是错误的。自动装配的工作原理只是因为它会故障回复到名称自动装配。如果我在DemoApplication中更改字段名称以不匹配bean名称,它将以与配置类相同的方式失败。
有没有办法强制解决依赖类型的依赖?
我创建了这个简单的例子只是为了帮助澄清我的意思 问题是。实际上我有两个基于Spring的不同库 引导,一个依赖于超类型,另一个依赖于子类型,我就是 因为第一个库的自动配置而被描述为碰撞 失败,因为它无法决定注入两者的bean bean池中的超类型和子类型。
[FYI]名字豆分辨率不是我正在寻找的。 p>
提前致谢!