Spring中使用@Bean和@Qualifier批注的Bean名称解析

时间:2019-11-26 13:19:09

标签: java spring spring-boot dependency-injection

我刚刚发现了我无法理解的Spring行为。我正在使用Spring Boot 1.5.x。

在配置类中,我声明了两个不同的bean。

@Configuration
class Config {
    @Bean("regularRestTemplate")
    public RestTemplate regularRestTemplate(String toLog) {
        return new RestTemplateBuilder().setConnectTimeout(100)
                                        .setReadTimeout(100)
                                        .additionalInterceptors((request, body, execution) -> {
                                            log.info("Inside the interceptor {}", toLog);
                                            return execution.execute(request, body);
                                        })
                                        .build();
    }
    @Bean("exceptionalRestTemplate")
    public RestTemplate regularRestTemplate() {
        return new RestTemplateBuilder().setConnectTimeout(100)
                                        .setReadTimeout(100)
                                        .build()
    }
}

然后,我有一个应该使用名为exceptionalRestTemplate的bean的类。

@Component
class Client {
    private RestTemplate restTemplate;
    @Autowired
    public Client(@Qualifier("exceptionalRestTemplate") RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    // Code that uses the injected rest template
}

由于我使用@Qualifier注释指定了要注入的bean的名称,因此我希望Spring注入名为exceptionalRestTemplate的bean。但是,实际上在注入过程中使用了名为regularRestTemplate的bean。

事实证明,问题出在配置类中声明Bean的方法的名称上。两者都被整理为regularRestTemplate。更改第二个方法名称,即可解决问题。

我的问题是,为什么?我知道Spring使用用@Bean@Component@Service等注释的类和方法的名称来为分辨率映射内的Java对象命名。 。但是,我认为在这些注释中输入名称会覆盖此行为。

有人告诉我怎么回事吗?

1 个答案:

答案 0 :(得分:4)

Bean限定符和Bean名称具有不同的含义。您限定了新bean的质量,但尝试覆盖它(参数无关紧要)。在您的应用程序中,您无法覆盖bean,因此只有第一个。

您可以检查此“理论”。在您的配置中添加参数

spring.main.allow-bean-definition-overriding=true

,然后再次启动您的应用程序。之后,您将只有另一个bean。

这是碰撞的解释。但是解决方案是将bean分离为不同的配置。