子类型和Spring相互依赖性解析与自动装配

时间:2017-06-11 19:00:44

标签: java spring spring-boot

我试图理解为什么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]名字豆分辨率不是我正在寻找的。

提前致谢!

0 个答案:

没有答案