微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

来自应用程序属性的 Spring Boot 不可变列表

如何解决来自应用程序属性的 Spring Boot 不可变列表

属性文件(yaml 文件)创建不可修改的列表时,我有点不知所措。这有效:

@Getter
@ConfigurationProperties(prefix = "device")
@Configuration
public class DeviceConfiguration {

    private final List<String> identifiers;

    @Value("${device.somekey.disabled:false}")
    private final boolean disabled;

    @Value("${device.someotherkey.number}")
    private final int number;

}

但我希望列表不可修改。此列表上的后续代码更改可能会在流程中产生非常严重的错误。所以我认为这样的事情会起作用,但它没有:

@Getter
@ConfigurationProperties(prefix = "device")
@Configuration
public class DeviceConfiguration {

    private final List<String> identifiers;

    private final boolean disabled;

    private final int number;

    @ConstructorBinding
    public DeviceConfiguration(final List<String> identifiers,@Value("${device.somekey.disabled:false}") final boolean disabled,@Value("${device.someotherkey.number}") final int number) {
        this.identifiers = Collections.unmodifiableList(identifiers);
        this.userkeySigningdisabled = userkeySigningdisabled;
        this.number = number;
    }
}

如果我将@ConstructorBinding 添加到我得到的类中:

  Cannot bind @ConfigurationProperties for bean 'DeviceConfiguration'. 
  Ensure that @ConstructorBinding has not been applied to regular bean

如果我将 @ConstructorBinding 添加到构造函数(如示例中),我得到:

  Failed to bind properties under 'device' ...
  Property: device.identifiers[5]
  Value: SomeValue
  Origin: class path resource [application.yaml] - 424:7
  Reason: No setter found for property: identifiers

我该如何解决这个问题?

谢谢!

巴特

解决方法

您以错误的方式使用了 @ConstructorBindingdocumentation 描述了正确的用法。注解需要放在类级别:

@Getter
@ConstructorBinding
@ConfigurationProperties(prefix = "device")
public class DeviceConfiguration {

    private final List<String> identifiers;

    private final boolean disabled;

    private final int number;

    public DeviceConfiguration(final List<String> identifiers,@Value("${device.somekey.disabled:false}") final boolean disabled,@Value("${device.someotherkey.number}") final int number) {
        this.identifiers = Collections.unmodifiableList(identifiers);
        this.userkeySigningDisabled = userkeySigningDisabled;
        this.number = number;
    }
}
,

你可以有一个重载的 setter 方法,Spring 会使用它进行绑定。在 setter 中,您可以执行在构造函数示例中显示的相同操作,例如

public void setIdentifiers(List<String> identifiers) {
    this.identifiers = Collections.unmodifiableList(identifiers);
}

这意味着 DeviceConfiguration 本身不会是不可变的,因为您必须删除标识符列表的 final 并公开一个 mutator setter 方法,但您仍然会实现 List 将是不可变的这一事实,正如它在setter 中,它只会执行一次,这与 getter 中每次都将标识符包装在一个新的不可修改列表中不同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。