I'm having the following configuration where I have two Spring beans with the same name from two different configuration classes.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class OtherRestTemplateConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
And I am injecting (and using) this bean like this:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class SomeComponent {
@Autowired
private RestTemplate restTemplate;
}
Now, my question is: why is Spring not complaining about having multiple beans with the same name? I would expect an exception here and having to add a @Primary
annotation to make sure that the correct one is being used.
On a side note: even if I add @Primary
it is still not always injecting the correct one.
Bean Overriding Spring beans are identified by their names within an ApplicationContext. Therefore, bean overriding is a default behavior that happens when we define a bean within an ApplicationContext that has the same name as another bean. It works by simply replacing the former bean in case of a name conflict.
We can do that via the @Qualifier annotation. For instance, we could specify that we want to use the bean returned by the johnEmployee method by using the @Qualifier annotation.
getBean() is case sensitive, however Spring uses custom bean naming strategy for @Component and @Bean classes.
You need to use the @Qualifier annotation together with @Annotated to resolve ambiguity between different beans with the same type. The parameter to Qualified is the name of the bean, which is automatically set based on the name of the method that is annotated with @Bean .
One of the beans is overriding other one because you use same name. If different names were used as @paweł-głowacz suggested, then in case of using
@Autowired
private RestTemplate myRestTemplate;
spring will complain because it finds two beans with same RestTemplate type and doesnt know which to use. Then you apply @Primary
to one of them.
More explanation here: more info
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With