Jjufi21
Jjufi21

Reputation: 11

No qualifying bean of type for 2 external maven dependencies

I'm working on a Spring Boot project that includes 2 maven dependencies, those dependencies both use org.springframework.web.client.RestTemplate so when in my project I do:

@Autowired
AClassUsingRestTemplate object;

it triggers:

No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected single matching bean but found 2: externalDependencyOneRestTemplate,externalDependencyTwoRestTemplate

I have the control of only one of those dependencies, where I've defined:

@Bean(name = "externalDependencyOneRestTemplate")
    public RestTemplate buildExternalDependencyOneRestTemplate() {
        final HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
                new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create().build());

        final RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
        restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(restTemplate.getRequestFactory()));

        return restTemplate;
    }

what can I do to fix it?

Do I have to tell ClassUsingRestTemplate to use a specifi RestTemplate implementations? If yes, how to do that?

Thanks

Upvotes: 0

Views: 572

Answers (3)

In addition to the @Qualifier approach mentioned by Andreas, there are two marginally better options with Boot:

  1. If your class is Spring-aware, inject RestTemplateBuilder instead of a RestTemplate, and use that for your customization. This allows for application-level configuration (e.g., adding authentication and tracing interceptors), and then further configuration on the specific service level (converters, failure handlers).

  2. Use @Bean to configure your AClassUsingRestTemplate, passing a RestTemplate to its constructor. (Constructor injection is recommended over field injection.) In @Bean, you can do whatever custom setup you want.

Upvotes: 0

Tom Elias
Tom Elias

Reputation: 782

Spring has found 2 types of beans it can inject in this Autowired member: "externalDependencyOneRestTemplate" or "externalDependencyTwoRestTemplate".

Spring cannot choose because it doesn't read your mind. You must help Spring by specifying which bean you want by using the Qualifier annotation:

@Autowired
@Qualifier("nameOfMyBeanHere")
AClassUsingRestTemplate object;

Additionally, it doesn't look like your RestTemplate implementation does anything special, i would suggest enabling Spring Autoconfiguration (which automatically creates a RestTemplate bean) and injecting it instead of creating your own.

Upvotes: 0

Andreas
Andreas

Reputation: 159086

Specify which one you want using @Qualifier:

@Autowired
@Qualifier("externalDependencyOneRestTemplate")
RestTemplate restTemplate;

If you cannot modify the code depending on the RestTemplate, you can specify which one is the default, i.e. which one to use if @Qualifier is not specified:

@Primary
@Bean(name = "externalDependencyOneRestTemplate")
public RestTemplate buildExternalDependencyOneRestTemplate() {
    ...
}

Upvotes: 1

Related Questions