@Service public class CustomerServiceImpl1 implements CustomerService{ @Override public Customer getCustomer(long id) { return new Customer(1, "Test1"); } }
and
@Service public class CustomerServiceImpl2 implements CustomerService{ @Override public Customer getCustomer(long id) { return new Customer(1, "Test1"); } }
Now, a client which injects in the CustomerService bean as a dependency will fail, as by default the injection of autowired fields is by type and there are two beans in the context of the same type. An error message along these lines is typically what is seen at startup:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [pkg.CustomerService] is defined: expected single matching bean but found 2: customerServiceImpl2,customerServiceImpl1
A standard fix for this is to inject by bean name instead of by type, this way:
public class ConfigTest { @Autowired @Qualifier("customerServiceImpl1") private CustomerService customerService; ... }
Note that I have made use of the bean naming convention for stereotype annotations which is described in more detail here
However there is another way to disambiguate which specific bean to inject in, and this is with the @Primary annotation. This annotation indicates that the target bean should be given precedence when autowiring by type. This begs the question, what happens if more than one bean of the same type is annotated with @Primary, well Spring will raise an exception like before. @Primary is expected to be applied on only bean of a specific type.
@Primary is also supported in Java Configuration, so @Bean methods can also be tagged with @Primary to indicate the higher precedence.
@Configuration public class TestConfiguration { @Bean @Primary public CustomerService customerService1() { return new CustomerServiceImpl1(); } @Bean public CustomerService customerService2() { return new CustomerServiceImpl2(); } }
Than you for tutorial it was helpfully for me!
ReplyDeleteBest Regards
Thank you for your post it was helpful for me!!
ReplyDeleteBest Regards,
Nice tutorial. Thanks much !!!
ReplyDeleteHi,
ReplyDeleteThere is also the javax.annotation.Priority annotation that can be used to select the right bean specifically when more than two beans implement the same interface.
https://javaee-spec.java.net/nonav/javadocs/javax/annotation/Priority.html
What to do if I want to get bean of the class which is not marked Primary?
ReplyDelete