我正在尝试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
但我找不到任何关于如何使用Yaml
springboot 设置的实例注册它的信息。
我至少在正确的轨道上吗?
编辑
我注意到ConstructorException
from 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