- Регистрация
- 23 Авг 2023
- Сообщения
- 3,969
- Реакции
- 0
- Баллы
- 36
Ofline
В мире Spring Boot почти каждый сталкивался с аннотациями
Именно для этого я разработал conditionals-spring-boot - маленькую библиотеку для расширенных conditional-аннотаций, полностью интегрируемую с Spring Boot 3 и Java 17.
В Spring Boot
Ниже можно увидеть несколько примеров использования аннотаций библиотеки:
Практически все аннотации можно повторять (кроме
Внутри библиотеки все property-based условия описаны через единый контракт
Если вам интересно попробовать, документация и примеры доступны на GitHub. (и поставьте звёздочку 😀)
@ConditionalOnProperty, @ConditionalOnBean и их собратьями. Они помогают конфигурировать бины динамически, но стандартные условия это только вершина айсберга. Что если вам нужен гибкий, декларативный, строго-типизированный, который понимает Collection, Map, Enum и т.д.?Именно для этого я разработал conditionals-spring-boot - маленькую библиотеку для расширенных conditional-аннотаций, полностью интегрируемую с Spring Boot 3 и Java 17.
Почему стандартные условия не всегда работают
В Spring Boot
@ConditionalOnProperty позволяет проверять простые свойства, но:
Нельзя писать простые сравнения и матчи с помощью аннотаций (@ConditionalOnExpressionне в счет).
Нельзя строго типизировать значение (в обычном Spring Boot есть только String и boolean).
Что умеет моя библиотека
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. (и поставьте звёздочку 😀)