9

Java 16 引入了Records,这有助于在编写携带不可变数据的类时减少样板代码。当我尝试@ConfigurationProperties按如下方式使用 Record 作为 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

4

2 回答 2

17

回答我自己的问题。

由于缺少无参数构造函数,Spring Boot 无法构造 bean 引发了上述错误。记录为每个成员隐式声明一个带有参数的构造函数。

Spring Boot 允许我们使用@ConstructorBinding注解通过构造函数而不是 setter 方法启用属性绑定(如文档和此问题的答案中所述)。这也适用于记录,所以这有效:

@ConfigurationProperties("demo")
@ConstructorBinding
public record MyConfigurationProperties(
        String myProperty
) {
}

更新:从 Spring Boot 2.6 开始,使用记录开箱即用@ConstructorBinding,当记录具有单个构造函数时不再需要。请参阅发行说明

于 2021-03-18T18:14:57.410 回答
2

如果您需要以编程方式声明默认值:

@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));
    }
}

@Validatedjava.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 问题

于 2021-07-13T07:26:41.957 回答