Как Spring обрабатывает ситуацию с несколькими бинами одного типа в контексте?

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

Ответ

Если в контексте Spring определено несколько бинов одного типа, возникает неоднозначность внедрения зависимостей. Без дополнительных указаний Spring выбросит NoUniqueBeanDefinitionException.

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

  1. Аннотация @Primary: Помечает бин как предпочтительный кандидат для автосвязывания.
  2. Аннотация @Qualifier: Позволяет указать конкретное имя бина при инжекции.
  3. Аннотация @Resource (JSR-250): Внедрение по имени бина.

Пример конфигурации и использования:

@Configuration
public class AppConfig {
    @Bean
    @Primary // Этот бин будет выбран по умолчанию
    public DataSource primaryDataSource() {
        return new H2DataSource();
    }
    @Bean
    public DataSource secondaryDataSource() {
        return new PostgresDataSource();
    }
}

@Component
public class MyService {
    // Внедрение по умолчанию (primaryDataSource)
    @Autowired
    private DataSource defaultDataSource;

    // Внедрение конкретного бина по имени
    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource specificDataSource;

    // Внедрение по имени с использованием @Resource
    @Resource(name = "secondaryDataSource")
    private DataSource namedDataSource;
}

Важно: Имя бина по умолчанию — это имя метода-создателя (primaryDataSource, secondaryDataSource).