Для чего используются аннотации @ConditionalOn в Spring Boot? Приведите пример.

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

Ответ

Аннотации @ConditionalOn... в Spring Boot — это часть механизма автоконфигурации. Они позволяют условно регистрировать бины или конфигурационные классы в контексте приложения в зависимости от состояния среды (наличие класса, свойства, бина и т.д.).

Распространённые аннотации:

  • @ConditionalOnClass — если указанный класс присутствует в classpath.
  • @ConditionalOnMissingClass — если класс отсутствует.
  • @ConditionalOnBean / @ConditionalOnMissingBean — если бин присутствует/отсутствует.
  • @ConditionalOnProperty — если определённое свойство имеет заданное значение.
  • @ConditionalOnWebApplication / @ConditionalOnNotWebApplication — в зависимости от типа приложения.

Пример 1: Создание бина только при наличии класса в classpath

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyAutoConfiguration {
    // Бин будет создан, только если в classpath есть класс 'com.example.ExternalService'
    @Bean
    @ConditionalOnClass(name = "com.example.ExternalService")
    public MyService myService() {
        return new MyService();
    }
}

Пример 2: Условная конфигурация на основе свойства application.yml

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeatureConfiguration {
    // Бин будет зарегистрирован, только если свойство 'app.feature.enabled' равно 'true'
    @Bean
    @ConditionalOnProperty(prefix = "app.feature", name = "enabled", havingValue = "true")
    public AdvancedService advancedService() {
        return new AdvancedService();
    }
}
# application.yml
app:
  feature:
    enabled: true # Если false, бин advancedService не будет создан.

Пример 3: Создание бина по умолчанию, если другой отсутствует

@Configuration
public class CacheConfig {
    // Создаём бин defaultCache, только если бин с именем 'redisCache' НЕ найден.
    @Bean
    @ConditionalOnMissingBean(name = "redisCache")
    public Cache defaultCache() {
        return new SimpleInMemoryCache();
    }
}

Зачем это нужно? Позволяет Spring Boot автоматически настраивать приложение в зависимости от добавленных зависимостей (spring-boot-starter-*) и параметров, избегая конфликтов и лишней конфигурации.