Что произойдет в Spring, если в контексте существуют два бина одного типа с разной реализацией?

«Что произойдет в Spring, если в контексте существуют два бина одного типа с разной реализацией?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Spring выбросит исключение NoUniqueBeanDefinitionException при попытке инжекции по типу (например, через @Autowired), так как контейнер не сможет однозначно определить, какой бин использовать.

Способы разрешения неоднозначности:

  1. Аннотация @Primary — помечает один бин как предпочтительный.

    @Configuration
    public class AppConfig {
    @Bean
    @Primary // Этот бин будет выбран по умолчанию
    public MyService primaryService() {
        return new PrimaryServiceImpl();
    }
    @Bean
    public MyService secondaryService() {
        return new SecondaryServiceImpl();
    }
    }
  2. Аннотация @Qualifier — явное указание имени конкретного бина.

    @Component
    public class ClientComponent {
    @Autowired
    @Qualifier("secondaryService") // Указываем конкретное имя бина
    private MyService service;
    }
  3. Совпадение имени поля с именем бина (работает в некоторых случаях, но ненадежно).

    @Autowired
    private MyService secondaryService; // Может инжектиться бин с именем "secondaryService"
  4. Инжекция всех бинов этого типа в коллекцию.

    @Autowired
    private List<MyService> allServices; // Инжектит оба бина

Рекомендация: Используйте @Qualifier для явного и понятного выбора нужной реализации.