record и @ConstructorBindingВместо традиционных
@Data + пустого конструктора можно сразу использовать Java 17 record для настройки свойств:📌 Почему это полезно?
🔴Полная иммутабельность: поля конфигов больше нельзя случайно перезаписать.
🔴Минимум «шаблонного» кода: не нужны геттеры, сеттеры,
toString(), equals() и т.д.🔴Чёткая связь с Java 17+ и актуальными best practices.
💡 Как сделать:
1. Подключаем зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Это нужно, чтобы IDE и Spring метаинфу подхватили.
2. Создаём
record с аннотацией:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
@ConstructorBinding
@ConfigurationProperties(prefix = "app.mail")
public record MailProperties(
String host,
int port,
String username,
String password
) {}
3. Регистрируем бин в Spring:
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class AppConfig { }
4. Конфигурируем в
application.yml (или .properties):
app:
mail:
host: smtp.example.com
port: 587
username: user@example.com
password: secret123
⚠️ Обратите внимание:
🔴Без
@ConstructorBinding Spring не сможет смотать значения в record’ы.🔴Уберите все сеттеры и по умолчанию конструктор генерируется автоматически.
🔴Если вам нужна валидация свойств, добавьте
@Validated и JSR-303 аннотации (@NotNull, @Min и т.д.).🧠 Что получилось?
🔴Минимум «мусора» в коде: один блок
record заменил класс с 4 полями, геттерами и конструктором.🔴Полная типобезопасность и поддержка автокомплита при обращении к полям.
🔴Быстрый переход на Java 17+ подходы без потери функциональности.
💡 Дополнительный лайфхак:
Если вам нужно разделить конфиги по окружениям (dev/prod), просто создайте два
record’а с разными префиксами или используйте @Profile. В Spring Boot 3 этот подход «из коробки» работает наилучшим образом.👉@BookJava