[英]Nested Spring configuration (ConfigurationProperties) in records
一个 map application.yaml
如何具有嵌套属性的 yaml 配置与 Java 中的类似记录结构?
例如,如果我们有以下 yaml:
foo:
bar:
something: 42
baz:
otherThing: true
color: blue
所需的记录结构将类似于以下内容:
@ConfigurationProperties(prefix = "foo")
@ConstructorBinding
public record Foo(
Bar bar,
Baz baz,
String color
) {}
// ---
@ConfigurationProperties(prefix = "foo.bar")
@ConstructorBinding
public record Bar(
int something
) {}
// ---
@ConfigurationProperties(prefix = "foo.baz")
@ConstructorBinding
public record Baz(
boolean otherThing
) {}
对于每个嵌套的 class,您不需要@ConfigurationProperties
。 它仅适用于根 class (Foo.class)。 然后通过在 class 上方插入@Component
或将@ConfigurationPropertiesScan
放在应用程序 class 上,将 Foo 设置为 Spring Bean。
原来我没有针对我遇到的问题提出正确的问题:/ 因此,对于人们从类似问题中找到这个主题的情况,我的实际问题的答案如下。
嵌套 yaml 试图在 model 层次结构上“捷径”出现问题,因此给出以下 yaml:
foo:
bar:
baz:
bum: "hello"
我试图 model 的层次结构如下:
@ConfigurationProperties(prefix = "foo")
@ConstructorBinding
public record Foo(BarBaz barBaz) {}
// ---
@ConfigurationProperties(prefix = "foo.bar.baz")
@ConstructorBinding
public record BarBaz(String bum) {}
这里出现的问题是Foo
不能为BarBaz
进行构造函数绑定(不知道为什么)。 因此,我发现了两种可能的解决方案:
1.做全建模(决定这是我比较喜欢的)
也就是说,不要试图跳过bar
的中间 model 。
@ConfigurationProperties(prefix = "foo")
@ConstructorBinding
public record Foo(Bar bar) {}
// ---
@ConfigurationProperties(prefix = "foo.bar")
@ConstructorBinding
public record Bar(Baz baz) {}
// ---
@ConfigurationProperties(prefix = "foo.bar.baz")
@ConstructorBinding
public record Baz(String bum) {}
2.嵌入更多嵌套时不要使用@ConstructorBinding
只需跳过Foo
中的构造函数绑定。
@ConfigurationProperties(prefix = "foo")
public record Foo(BarBaz barBaz) {}
// ---
@ConfigurationProperties(prefix = "foo.bar.baz")
@ConstructorBinding
public record BarBaz(String bum) {}
虽然更简单,但它不太一致。
我认为为简化起见,您可以只创建一个文件:
@ConfigurationProperties(prefix = "foo")
public record Foo(Bar bar) {
public record Bar(Baz baz) {
public record Baz(String bum) {}
}
}
这在 spring-boot 中运行良好,您无需重复注释,使用时只需使用:
String bumVal = foo.bar().baz().bum();
其中 foo 只是注入到您需要它的 Bean(s) 中。
我什至删除了@ConsructorBinding
,因为从 spring-boot 2.6 开始,只要记录只定义一个构造函数,就不再需要它了,请参阅发行说明。
上面的配置与你自己的答案结构有关,但这里也是原始问题结构的紧凑方式:
@ConfigurationProperties(prefix = "foo")
public record Foo(Bar bar, Baz baz, String color) {
public record Bar(String something) {
}
public record Baz(String otherThing) {
}
}
我发现record
类型对于这个用例非常有用,因为它非常紧凑并且不需要编写太多代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.