Как использовать @ConfigurationProperties с записями?

В Java 16 появились записи, которые помогают сократить стандартный код при написании классов, несущих неизменяемые данные. Когда я пытаюсь использовать Record as @ConfigurationProperties bean следующим образом, я получаю следующее сообщение об ошибке:

@ConfigurationProperties("demo")
public record MyConfigurationProperties(
        String myProperty
) {
}
***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.example.demo.MyConfigurationProperties required a bean of type 'java.lang.String' that could not be found.

Как я могу использовать записи как @ConfigurationProperties?


person Moritz    schedule 18.03.2021    source источник


Ответы (2)


Отвечая на мой собственный вопрос.

Вышеупомянутая ошибка возникает из-за того, что Spring Boot не может создать bean-компонент из-за отсутствия конструктора без аргументов. Записи неявно объявляют конструктор с параметром для каждого члена.

Spring Boot позволяет нам использовать аннотацию @ConstructorBinding для включения привязки свойств с помощью конструктора вместо методов установки (как указано в документы и ответ на этот вопрос). Это также работает для записей, так что это работает:

@ConfigurationProperties("demo")
@ConstructorBinding
public record MyConfigurationProperties(
        String myProperty
) {
}
person Moritz    schedule 18.03.2021
comment
Я получаю сообщение об ошибке, говорящее, что он окончательный и не должен быть окончательным, когда я использую именно этот метод. В чем может быть проблема? - person TheRealChx101; 01.07.2021

Если вам нужно программно объявить значения по умолчанию:

@ConfigurationProperties("demo")
public record MyConfigurationProperties(String myProperty) { 
    
    @ConstructorBinding
    public MyConfigurationProperties(String myProperty) {
        this.myProperty = Optional.ofNullable(myProperty).orElse("default");
    }
}

java.util.Optional свойства:

@ConfigurationProperties("demo")
public record MyConfigurationProperties(Optional<String> myProperty) {

    @ConstructorBinding
    public MyConfigurationProperties(String myProperty) {
        this(Optional.ofNullable(myProperty));
    }
}

@Validated и java.util.Optional в комбинации:

@Validated
@ConfigurationProperties("demo")
public record MyConfigurationProperties(@NotBlank String myRequiredProperty,
                                        Optional<String> myProperty) {

    @ConstructorBinding
    public MyConfigurationProperties(String myRequiredProperty, 
                                     String myProperty) {
        this(myRequiredProperty, Optional.ofNullable(myProperty));
    }
}

На основании этой проблемы Spring Boot.

person lpandzic    schedule 13.07.2021