【问题标题】:How to use @ConfigurationProperties with Records?如何将@ConfigurationProperties 与记录一起使用?
【发布时间】:2021-06-16 04:37:11
【问题描述】:

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

【问题讨论】:

  • 当您还需要@Configuration 注释时,这些注释不能是最终的,但记录是,这应该如何工作?
  • @SebastiaanvandenBroek 您可以在 EnableConfigurationProperties 配置中定义它,而不是使用配置注释

标签: java spring spring-boot java-16


【解决方案1】:

回答我自己的问题。

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

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

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

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

【讨论】:

  • 我得到一个错误,说它是最终的,当我完全使用这种方法时它不应该是最终的。可能是什么问题?
【解决方案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 issue

【讨论】:

  • 您知道如何使用记录来声明复杂的参数并让属性像非记录类一样遵循分层结构吗?
  • 我不记得有关该案例的任何具体内容,常规嵌套记录不起作用吗?
  • 对我来说,这些解决方案根本不起作用:/
  • 我有同样的问题,我不认为嵌套工作......
  • 确实不行。我在 spring boot github tracker github.com/spring-projects/spring-boot/issues/28797 上创建了一个新问题
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 2021-02-24
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
相关资源
最近更新 更多