【问题标题】:Nested Spring configuration (ConfigurationProperties) in records记录中嵌套的 Spring 配置(ConfigurationProperties)
【发布时间】:2022-01-12 14:45:42
【问题描述】:

如何将具有嵌套属性的application.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
) {}

【问题讨论】:

  • 乍一看它应该可以工作。您是否尝试过从记录BazBar 中删除@ConfigurationProperties,因为它将被Foo 中的属性名称拉取?或者,将记录 BazBar 嵌套在 Foo 中,并从嵌套记录中删除 @ConfigurationProperties(如果这是您可以接受的解决方案)。
  • 事实证明确实如此,事实证明我没有正确地重建我的问题。我终于设法从它的工作原理中弄清楚出了什么问题,然后一步一步地潜水。如果我知道要问什么,将发布我打算问的问题的答案
  • 关于 @ConfigurationProperties 的删除只有在我不注入 Bar 和或 Baz 而没有 Foo 时才有效。我希望能够只注入我需要限制耦合和依赖关系的东西,所以我实际上不建议删除它们:)

标签: java spring spring-boot java-17 java-record


【解决方案1】:

每个嵌套类都不需要@ConfigurationProperties。它仅适用于根类(Foo.class)。然后通过在类上方插入@Component 或将@ConfigurationPropertiesScan 放在Application 类上,将Foo 设为Spring Bean。

【讨论】:

  • 谢谢,原来我没有问我打算问的问题。接受您的回答,因为您回答了我实际提出的问题,并将在下面添加我想要的答案,以防其他人遇到类似问题:)
  • 关于 @ConfigurationProperties 的删除只有在我不注入 Bar 和或 Baz 而没有 Foo 时才有效。我希望能够只注入我需要限制耦合和依赖关系的东西,所以我实际上不建议删除它们:)
【解决方案2】:

事实证明我没有针对我遇到的问题提出正确的问题:/ 因此,对于人们从类似问题中找到此主题的情况,我的实际问题的答案如下。

问题在于嵌套 yaml 试图在模型层次结构上“走捷径”,因此给出以下 yaml:

foo:
    bar:
        baz:
            bum: "hello"

我试图将层次结构建模如下:

@ConfigurationProperties(prefix = "foo")
@ConstructorBinding
public record Foo(BarBaz barBaz) {}

// --- 

@ConfigurationProperties(prefix = "foo.bar.baz")
@ConstructorBinding
public record BarBaz(String bum) {}

这里出现了Foo 无法为BarBaz 进行构造函数绑定的问题(不知道为什么)。所以我找到了两种可能的解决方案:

1.做完整的造型(决定这是我喜欢的)

也就是说,不要试图跳过bar的中间模型。

@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) {}

虽然更简单,但不太一致。

【讨论】:

    猜你喜欢
    • 2015-06-17
    • 2017-08-21
    • 2020-01-07
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 2011-08-12
    相关资源
    最近更新 更多