Группа настроек: @ConfigMapping
Когда настроек становится много, отдельные поля с @ConfigProperty неудобны: имена ключей повторяются строками в разных классах, и опечатку легко не заметить. Config mapping решает это: вы описываете группу настроек одним интерфейсом, а Quarkus заполняет его значениями из файла и проверяет их при старте. Это рекомендуемый в Quarkus способ работы с собственными настройками.
Интерфейс настроек
Создайте интерфейс в пакете приложения:
// src/main/java/com/example/blog/BlogConfig.java
package com.example.blog;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import java.util.Optional;
@ConfigMapping(prefix = "blog")
public interface BlogConfig {
String title();
@WithDefault("20")
int pageSize();
Optional<String> owner();
}prefix = "blog" связывает интерфейс с ключами blog.*. Каждый метод — одна настройка. Имя метода переводится в ключ автоматически: pageSize() читает blog.page-size, title() — blog.title.
| Что в интерфейсе | Что это значит |
|---|---|
String title() | Обязательная настройка, без неё приложение не стартует |
@WithDefault("20") | Значение по умолчанию |
Optional<String> owner() | Необязательная настройка |
@WithName("page") | Своё имя ключа вместо имени метода |
Использование
Интерфейс внедряется как обычный бин. Перепишем InfoResource:
// src/main/java/com/example/blog/InfoResource.java
package com.example.blog;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@Path("/info")
public class InfoResource {
@Inject
BlogConfig config;
@GET
public String info() {
String owner = config.owner().orElse("неизвестен");
return config.title() + ", постов на странице: " + config.pageSize() + ", автор: " + owner;
}
}Файл application.properties остаётся тем же, что в прошлом уроке. В dev mode:
curl http://localhost:8080/infoБлог Анны (разработка), постов на странице: 10, автор: неизвестен
Ключа blog.owner в файле нет, поэтому Optional пустой. Добавьте строку blog.owner=Анна — и после обновления страницы ответ закончится на автор: Анна.
Вложенные группы
Метод может вернуть другой интерфейс — так получается вложенная группа:
// src/main/java/com/example/blog/BlogConfig.java
Comments comments();
interface Comments {
@WithDefault("true")
boolean enabled();
@WithDefault("1000")
int maxLength();
}Эти методы читают ключи blog.comments.enabled и blog.comments.max-length.
Тот же бин в любом месте
BlogConfig можно внедрить в сервис, ресурс, задачу по расписанию — везде одни и те же значения. В уроке о запросах к базе мы возьмём из него размер страницы для списка постов.
Частая ошибка
Config mapping проверяет не только отсутствующие ключи, но и лишние. Если в файле опечатка, например blog.titel=Опечатка, приложение не стартует:
SRCFG00050: blog.titel in PropertiesConfigSource[source=file:/.../target/classes/application.properties]:4 does not map to any root
Сообщение указывает ключ и номер строки в файле. Это одно из главных преимуществ @ConfigMapping перед @ConfigProperty: с отдельными полями опечатка в имени ключа молча превратилась бы в значение по умолчанию.