Как использовать @ConfigurationProperties с @Conditional в Spring

Вопрос или проблема

Мне нравится строгая типизация и возможности рефакторинга в @ConfigurationProperties. Я хочу использовать условные бины, но не хочу использовать @ConditionalOnProperty, потому что он требует указания имени свойства в сыром виде.

Я попробовал следующий подход

@Conditional(SecurityEnabledCondition.class)
@Bean ...


public class SecurityEnabledCondition implements Condition {

  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    ClientProperties clientProperties = context.getBeanFactory().getBean(ClientProperties.class);
    return clientProperties.isSecured();
  }
}

Но бин не найден, так как Condition не предназначен для взаимодействия с бинами. Как использовать @ConfigurationProperties с @Conditional в Spring?

Ответ или решение

Для использования @ConfigurationProperties вместе с @Conditional в Spring, нужно учитывать, что @Conditional не может взаимодействовать напрямую с бинами, так как он работает на этапе создания контекста. Тем не менее, есть способ достичь желаемого результата, не прибегая к строковым именам свойств.

Ниже приведены шаги, которые помогут вам использовать @ConfigurationProperties в комбинации с @Conditional.

Шаг 1: Определите ваш класс @ConfigurationProperties

Создайте класс для хранения свойств конфигурации, который будет использовать аннотацию @ConfigurationProperties:

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "client")
public class ClientProperties {
    private boolean secured;

    // Геттеры и сеттеры
    public boolean isSecured() {
        return secured;
    }

    public void setSecured(boolean secured) {
        this.secured = secured;
    }
}

Шаг 2: Создайте условие для вашего бина

Создайте класс, реализующий интерфейс Condition, который будет проверять состояние вашего бина ClientProperties.

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.stereotype.Component;

@Component
public class SecurityEnabledCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // Получаем бин ClientProperties из контекста
        ClientProperties clientProperties = context.getBeanFactory().getBean(ClientProperties.class);
        return clientProperties.isSecured();
    }
}

Шаг 3: Используйте условие в вашем бине

Теперь вы можете использовать @Conditional для создания условия на основе ClientProperties в вашем конфигурационном классе:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SecurityConfiguration {

    @Conditional(SecurityEnabledCondition.class)
    @Bean
    public SecurityService securityService() {
        return new SecurityService();
    }
}

Шаг 4: Настройка свойств

Не забудьте добавить ваши свойства в файл конфигурации (например, application.yml или application.properties):

client:
  secured: true

Пример класса защиты

Пример класса SecurityService, который вы создаете условно:

public class SecurityService {
    // Реализация сервиса безопасности
}

Заключение

Теперь, когда вы запускаете приложение, если свойство secured в ClientProperties установлено в true, то будет создан бин SecurityService. Этот подход позволяет вам использовать @ConfigurationProperties для конфигурации и добавлять условия на основе значений этих свойств, обеспечивая типизацию и легкость рефакторинга.

Оцените материал
Добавить комментарий

Капча загружается...