0

我正在尝试application.yaml通过从配置 bean中读取配置项列表@ConfigurationProperties。该列表可能包含具有已定义基本类型的对象:

@ConfigurationProperties("myapp")
public class MyConfiguration {
   private Set<Point> points;
}

public abstract class Point {
  private String name;
}

public class QuantityPoint extends Point {
  private Number value;
}

public class StatePoint extends Point {
  private String state;
}

application.yaml这是我想象的一个例子:

myapp:
  points:
  - name: foo
    value: 5
  - name: bar
    state: bar

我发现了一些我认为正在解决这个确切问题的帖子,但到目前为止没有任何建议有效。ConfigurationProperties("myapp.points")我尝试在子类型上玩,Point但如前所述:没有任何效果。

老实说,我想知道解析器应该如何区分类型。一定有一个type参数缺失,类似于我们如何使用 Jackson 将实体转换为 json。

目前,我得到了Point(当我删除abstract修饰符时)和字段的实例value并且state丢失了。

编辑

我想我在找出需要做什么方面取得了一些进展。显然,Spring 正在使用 SnakeYaml 来解析文件,并且该库使用 yaml 标签来指示类型信息,因此我的 yaml 应该看起来像

myapp:
  points:
  - !!foo
    name: foo
    value: 5
  - !!bar
    name: bar
    state: bar

有一些内置标签,但我需要自己注册。我找到了如何通过扩展来编写自定义构造函数的信息,AbstractConstruct但我找不到任何关于如何使用Yamlspringboot 设置的实例注册它的信息。

我至少在正确的轨道上吗?

编辑

我注意到ConstructorExceptionfrom snakeyaml 在启动过程中出现得这么早,可能无法将 my 添加SafeConstructor到过程中:

@Component
public class FooConstructor extends SafeConstructor {

    public FooConstructor() {
        this.yamlConstructors.put(new Tag("!foo"), new ConstructFoo());
    }
    
    private class ConstructFoo extends AbstractConstruct {
        @Override
        public Object construct(Node node) {
            String val = (String) constructScalar((ScalarNode) node);
            System.out.println(val);
            return null;
        }
    }
}
06:48:29.380 [restartedMain] ERROR org.springframework.boot.SpringApplication - Application run failed
org.yaml.snakeyaml.constructor.ConstructorException: could not determine a constructor for the tag !state
 in 'reader', line 5, column 5:
      - !foo
4

0 回答 0