如何在Spring Boot中通过@ConfigurationProperties获得嵌套的基于Spel表达式的对象



这在我的application.yml

translations:
en:
title: 'english'
description: 'english text'
fr:
title: 'french'
description: 'french text'
de:
title: 'german'
description: 'french text'
codes:
GB:
# I am assuming that en here will have an object with both title and description properties
en: ${translations.en}
CA:
en: ${translations.en}
fr: ${translations.fr}
DE:
en: ${translations.en}
fr: ${translations.fr}
de: ${translations.de}

现在考虑一下这段代码(删除了不必要的getter等,为了简洁起见,还使用了lombok项目(

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
// Inner classes, but these can be outside as well
@ConfigurationProperties
@Getter
@Component
class Config {
Map<String, Map<String, LanguageDTO>> codes;
}
@Data
@AllArgsConstructor
class LanguageDTO {
String title;
String description;
}
@Autowired
Config config;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// Getting error on this line below
Map<String, Map<String, LanguageDTO>> codes = config.getCodes();
}
}

现在,当我启动应用程序时,我会收到这样的错误:

APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'codes.gb.en' to com.example.demo.DemoApplication$LanguageDTO:
Property: codes.gb.en
Value: ${translations.en}
Origin: class path resource [application.yml]:24:9
Reason: No converter found capable of converting from type [java.lang.String] to type [com.example.demo.DemoApplication$LanguageDTO]
Action:
Update your application's configuration

我想要什么

我希望能够以Map<String, Map<String, LanguageDTO>的身份阅读代码。也就是说,我应该能够进行config.getCodes().get("GB").get("en")->其应当依次具有CCD_ 4的数据类型。

我认为这是不可行的:Spring只支持application.yaml文件中的简单属性占位符(据我所知(。不过,您可以利用YAML格式的内置功能、锚点和别名:

translations:
en: &en
title: 'english'
description: 'english text'
fr: &fr
title: 'french'
description: 'french text'
de: &de
title: 'german'
description: 'french text'
codes:
GB:
en: *en
CA:
en: *en
fr: *fr
DE:
en: *en
fr: *fr
de: *de

要使其工作,LanguageDTO类需要有setter和默认构造函数@AllArgsConstructor无法工作。或者,您可以尝试将它与构造函数绑定结合使用,尽管我不确定这是否可能。

最新更新