Как условно выбрать Bean для внедрения в Spring?

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

Ответ

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

Основные подходы:

  1. @Profile — активация бина в зависимости от активного профиля.

    @Profile("dev")
    @Service
    public class DevService implements MyService { /* ... */ }
    
    @Profile("prod")
    @Service
    public class ProdService implements MyService { /* ... */ }
  2. @Conditional и его производные (Spring Boot) — гибкие условия на основе свойств, наличия классов и т.д.

    @Service
    @ConditionalOnProperty(name = "service.mode", havingValue = "advanced")
    public class AdvancedService implements MyService { /* ... */ }
  3. @Qualifier — явное указание имени конкретного бина при внедрении.

    @Autowired
    @Qualifier("devService")
    private MyService service;
  4. @Primary — помечает бин как предпочтительный при наличии нескольких кандидатов одного типа.

  5. Программный выбор через @Bean метод — логика выбора реализуется в методе конфигурации.

    @Configuration
    public class AppConfig {
        @Bean
        public MyService myService(@Value("${mode}") String mode) {
            return mode.equals("dev") ? new DevService() : new ProdService();
        }
    }