AI conditionals-spring-boot: расширяем возможности @Conditional

  • Автор темы Автор темы AI
  • Дата начала Дата начала

AI

Команда форума
Редактор
Регистрация
23 Авг 2023
Сообщения
3,969
Реакции
0
Баллы
36
Ofline
В мире Spring Boot почти каждый сталкивался с аннотациями @ConditionalOnProperty, @ConditionalOnBean и их собратьями. Они помогают конфигурировать бины динамически, но стандартные условия это только вершина айсберга. Что если вам нужен гибкий, декларативный, строго-типизированный, который понимает Collection, Map, Enum и т.д.?

Именно для этого я разработал conditionals-spring-boot - маленькую библиотеку для расширенных conditional-аннотаций, полностью интегрируемую с Spring Boot 3 и Java 17.

Почему стандартные условия не всегда работают​


В Spring Boot @ConditionalOnProperty позволяет проверять простые свойства, но:


  • Нельзя писать простые сравнения и матчи с помощью аннотаций (@ConditionalOnExpression не в счет).


  • Нельзя строго типизировать значение (в обычном Spring Boot есть только String и boolean).

Что умеет моя библиотека​

7af2a976776798e76c7f18de48ea6e8e.jpg

1. Поддержка многих часто используемых типов:​


Ниже можно увидеть несколько примеров использования аннотаций библиотеки:

@ConditionalOnStringProperty​


Код:
@ConditionalOnStringProperty(
        name = "app.region",
        havingValue = "eu",
        trim = true
)

Код:
@ConditionalOnStringProperty(
        name = "app.region",
        havingValue = "EU",
        ignoreCase = true
)

Код:
@ConditionalOnStringProperty(
        name = "app.version",
        havingValue = "v\\d+\\.\\d+",
        matchType = StringMatchType.MATCHES
)

@ConditionalOnIntegerProperty​


Код:
@ConditionalOnIntegerProperty(
        name = "app.threads",
        havingValue = 4
)

Код:
@ConditionalOnIntegerProperty(
        name = "app.threads",
        havingValue = 16,
        matchType = ComparableMatchType.LESS_THAN
)

@ConditionalOnFloatProperty​


Код:
@ConditionalOnFloatProperty(
        name = "app.ratio",
        havingValue = 0.5f
)

Код:
@ConditionalOnFloatProperty(
        name = "app.ratio",
        havingValue = 0.7F,
        matchType = ComparableMatchType.GREATER_THAN_OR_EQUAL
)

@ConditionalOnDurationProperty​


Код:
@ConditionalOnDurationProperty(
        name = "app.timeout",
        havingValue = "5s",
        matchType = ComparableMatchType.GREATER_THAN
)

Код:
@ConditionalOnDurationProperty(
        name = "app.timeout",
        havingValue = "10s"
)

Код:
@ConditionalOnCharacterProperty(
        name = "app.letter",
        havingValue = 'A'
)

@ConditionalOnCollectionProperty​


Код:
@ConditionalOnCollectionProperty(
        name = "app.tags",
        havingValue = {"red", "blue"},
        matchType = CollectionMatchType.CONTAINS_ALL
)

Код:
@ConditionalOnCollectionProperty(
        name = "app.tags",
        havingValue = {"yellow", "green"},
        matchType = CollectionMatchType.CONTAINS_ANY
)

Код:
@ConditionalOnCollectionProperty(
        name = "app.tags",
        size = 3
)

@ConditionalOnMapProperty​


Код:
@ConditionalOnMapProperty(
        name = "app.labels",
        havingValue = {                         // массив ключ-значение
                "env", "prod",
                 "region", "eu"
        },
        matchType = MapMatchType.CONTAINS_ALL
)

Код:
@ConditionalOnMapProperty(
        name = "app.labels",
        havingValue = {"env", "prod"},  // массив ключ-значение
        matchType = MapMatchType.CONTAINS_ANY
)

@ConditionalOnEnumProperty​


Код:
@ConditionalOnEnumProperty(
        name = "app.labels",
        havingValue = "info",               // не кейс-сенситив
        enumType = LogLevel.class
)

enum LogLevel {
    TRACE, DEBUG, INFO, WARN, ERROR
}

2. Repeatable и контейнерные аннотации​


Практически все аннотации можно повторять (кроме @ConditionalOnOs и @ConditionalOnPortAvailable).

3. Унифицированная спецификация через PropertySpec​

4. Проверку ОС:​


Код:
@ConditionalOnOs("linux")

5. Проверку занятости порта:​


Код:
@ConditionalOnPortAvailable(8080)

Внутри библиотеки все property-based условия описаны через единый контракт PropertySpec + PropertySpecMatcher. Это минимизирует копипасту и упрощает тестирование.

Кому это будет полезно​


  • Разработчикам библиотек и модулей для Spring Boot.


  • Командам, которые пишут DSL на основе configuration properties.


  • Тем, кто сталкивался с boilerplate и ограничениями стандартных @Conditional аннотаций.

Заключение​


Если вам интересно попробовать, документация и примеры доступны на GitHub. (и поставьте звёздочку 😀)
 
Назад
Сверху Снизу
Яндекс.Метрика Рейтинг@Mail.ru