No qualifying bean, expected single matching bean but found 2

15,186

If you intend to express annotation-driven injection by name, do not primarily use @Autowired, even if is technically capable of referring to a bean name through @Qualifier values. Instead, use the JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.

As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through @Autowired, because type matching is not properly applicable to them. Use @Resource for such beans, referring to the specific collection or map bean by unique name.

@Autowired applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast, @Resource is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.


Try to set using value instead of name OR use @Primary

@Bean(value="server1BasicAuthClient")
@Bean(value="server2BasicAuthClient")

Refer 1 Refer 2

Share:
15,186
brmd
Author by

brmd

Updated on June 21, 2022

Comments

  • brmd
    brmd almost 2 years

    I searched on both the internet and on stack overlow but can't seem to find a solution to my problem:

    Unable to find bean reference for type 'class com.consol.citrus.http.client.HttpClient'Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.consol.citrus.http.client.HttpClient' available: expected single matching bean but found 2: server1BasicAuthClient,server2BasicAuthClient
    

    To sketch some background information: I have to make a small application using Spring 5 and Citrus Framework to automate our integration tests.

    I defined as following my Beans:

    @Configuration 
    public class EndpointAuthentication {
    
    public String server1Host;
    
    public int server1Port;
    
    public String server2Host;
    
    public int server2Port;
    
    @Bean(name="server1BasicAuthClient")
    public com.consol.citrus.http.client.HttpClient server1BasicAuthClient() throws Exception {
        return CitrusEndpoints.http()
                .client()
                .requestUrl(String.format("http://%s:%s/", server1Host, server1Port))
                .requestFactory(sslRequestFactory(server1Host,server1Port))
                .build();
    }
    
    @Bean(name="server2BasicAuthClient")
    public com.consol.citrus.http.client.HttpClient server2BasicAuthClient() throws Exception {
        return CitrusEndpoints.http()
                .client()
                .requestUrl(String.format("http://%s:%s/", server2Host, server2Port))
                .requestFactory(sslRequestFactory(server2Host,server2Port))
                .build();
    }
    }
    

    And I tried to inject my Bean like this,

    public class AuthenticationIT {
    
    @Autowired
    @Qualifier("server1BasicAuthClient")
    @CitrusEndpoint
    private HttpClient server1BasicAuthClient;
    
    @Autowired
    @Qualifier("server2BasicAuthClient")
    @CitrusEndpoint
    private HttpClient server2BasicAuthClient;
    ....
    }
    

    Any ideas where and how to fix the issue ?

    Thanks in advance.

  • brmd
    brmd about 5 years
    Thanks a lot for your response, Primary and resource annotations works for me. I changed my implementation to use a resource annotation.