1

我在 SpringBoot 中意识到了一个奇怪的行为。

在 yml 文件中,我有以下配置:

main:
  record-id:
    start-position: 1
    value: 1
    enabled: true
  record-name:
    start-position: 2
    value: main
    enabled: true
  invented:
    start-position: 3
    value: 01012020
    enabled: false

这些是它的类:

public class FieldType {
  private Integer startPosition;
  private String value;
  private Boolean enabled;
  getters/setters
}

@Component
@ConfigurationProperties(prefix = "main")
public class Main {
  private FieldType recordId;
  private FieldType recordName;
  private FieldType invented;
  getters/setters <-- sometimes without getters
}

如您所见,主类具有@ConfigurationProperties注释以将 yml 中的属性加载到该 bean 中。

这是我发现的:

  1. 如果我为主类中的字段提供吸气剂,那么有时主调用中的字段保持为空,因此不会启动
  2. 如果我重新启动 SpringBoot,则随机其他(1 个或多个)字段保持为空,因此未启动
  3. 如果我重新启动 SpringBoot n 次,那么,随机字段一次又一次地保持为空
  4. 如果我为主类中的字段提供 getter ,那么无论我重新启动 SpringBoot 多少次,所有字段都将始终从 tye yml 文件中实例化

为什么是这样?为什么 SpringBoot 需要在 yml 中表示属性的字段的 getter?

4

1 回答 1

2

您不需要 getter 来绑定属性,如果您使用默认构造函数,则需要 setter 来绑定属性,文档

如果嵌套 POJO 属性已初始化(如前面示例中的 Security 字段),则不需要 setter。如果您希望活页夹使用其默认构造函数动态创建实例,则需要一个 setter。

如果您正在初始化FieldTypeinMain类,那么您也不需要设置器

@Component
@ConfigurationProperties(prefix = "main")
public class Main {
    private FieldType recordId = new FieldType();
    private FieldType recordName = new FieldType();
    private FieldType invented = new FieldType();

 }

您还可以通过完全避免设置器来使用构造函数绑定

public class FieldType {
   private Integer startPosition;
   private String value;
   private Boolean enabled;
   
   public FieldType(Integer startPosition, String value, Boolean enabled) {
         this.startPosition = startPosition;
         this.value = value;
         this.enabled = enabled

  }

  @ConstructorBinding
  @ConfigurationProperties(prefix = "main")
  public class Main {
       private FieldType recordId;
       private FieldType recordName;
       private FieldType invented;

  public Main(FieldType recordId,FieldType recordName,FieldType invented) {
       this.recordId = recordId;
       this.recordName = recordName;
       this.invented = invented;

  }

只是关于构造函数绑定的注释

要使用构造函数绑定,必须使用 @EnableConfigurationProperties 或配置属性扫描启用该类。您不能对由常规 Spring 机制创建的 bean 使用构造函数绑定(例如,@Component bean、通过 @Bean 方法创建的 bean 或使用 @Import 加载的 bean)

于 2020-12-16T20:39:26.570 回答