Как добавить дефолтные значения в properties файлы Spring
Что проверяют
Понимаете ли вы, откуда Spring берёт значение свойства и в каком порядке источники перекрывают друг друга. Вопрос про дефолты быстро переходит в уточнение: если одно и то же свойство задано в application.properties, в переменной окружения и в аргументах запуска, какое победит?
Как отвечать
Способов несколько, и хорошо назвать их вместе с областью применения:
- дефолт в плейсхолдере
@Value:@Value("${app.timeout:30}"). Значение после двоеточия подставится, если свойства нет ни в одном источнике. Пустой дефолт пишется как${app.name:}; - плейсхолдер в самом файле:
app.url=${APP_URL:http://localhost:8080}, удобно для значений из окружения с запасным вариантом; @ConfigurationProperties: дефолт задаётся инициализатором поля, а при привязке через конструктор, в том числе для record, аннотацией@DefaultValueна параметре. Настройки собраны в одном классе, проверяются через@Validated, аspring-boot-configuration-processorгенерирует метаданные для подсказок в IDE;- отдельный слой дефолтов:
@PropertySource("classpath:defaults.properties")илиSpringApplication.setDefaultProperties(...). Оба источника по приоритету нижеapplication.properties, поэтому годятся как нижний слой.
Порядок источников в Spring Boot от сильного к слабому, упрощённо: аргументы командной строки, системные свойства Java, переменные окружения, application-{profile}.properties, application.properties, @PropertySource, значения по умолчанию из SpringApplication. Переменная APP_TIMEOUT за счёт relaxed binding попадает в app.timeout.
Где спотыкаются
Путают ${...} и #{...}. Первое это плейсхолдер свойства, второе выражение SpEL, и дефолт через двоеточие работает только в первом.
Ожидают дефолт, когда свойство задано пустым. Строка app.timeout= означает, что свойство существует, подставится пустая строка, а не значение по умолчанию, и числовое поле получит ошибку конвертации или null.
Подключают YAML через @PropertySource. Без собственной PropertySourceFactory он разбирает файл как .properties, и вложенные ключи прочитаются неправильно без всякой ошибки.