Как Spring разрешает неоднозначность, когда в контексте присутствует несколько бинов одного типа?

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

Ответ

Spring выбрасывает NoUniqueBeanDefinitionException, если не указано, какой именно бин нужно внедрить. Есть несколько способов разрешить эту неоднозначность:

  • Аннотация @Primary. Помечает бин как предпочтительный для автоматического связывания.

    @Configuration
    public class AppConfig {
        @Bean
        @Primary // Этот бин будет выбран по умолчанию
        public DataSource primaryDataSource() { ... }
    
        @Bean
        public DataSource secondaryDataSource() { ... }
    }
  • Аннотация @Qualifier. Позволяет явно указать имя конкретного бина при инъекции.

    @Service
    public class MyService {
        @Autowired
        @Qualifier("secondaryDataSource") // Указываем конкретный бин
        private DataSource dataSource;
    }
  • Инъекция по имени поля. Если имя поля совпадает с именем нужного бина (редко используемый явно способ).

    @Autowired
    private DataSource secondaryDataSource; // Будет найден бин с именем 'secondaryDataSource'
  • Инъекция коллекции всех бинов. Полезно, когда нужны все реализации интерфейса.

    @Autowired
    private List<DataSource> allDataSources; // Внедрятся все бины типа DataSource

@Primary задает поведение по умолчанию, а @Qualifier обеспечивает точный контроль.