簡體   English   中英

記錄中嵌套的 Spring 配置(ConfigurationProperties)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM