如何在 Spring Boot 中通过 @ConfigurationProperties 获取嵌套的基于 Spel 表达式的对象?
How to get nested Spel expression based objects through @ConfigurationProperties in Spring Boot?
这是我的 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 等,为了简洁起见还使用 project 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")
--> 其数据类型应为 LanguageDTO
.
我认为它不可行:Spring 仅支持 application.yaml 文件中的简单 属性 占位符(据我所知)。不过,您可以做的是利用 YAML 格式 built-in 功能,anchors and aliases:
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
For it to work, the LanguageDTO
class needs to have setters and a default constructor. @AllArgsConstructor won't work. Alternatively you might try to get it work in conjunction with constructor binding, although I'm not sure if it's possible.
这是我的 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 等,为了简洁起见还使用 project 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")
--> 其数据类型应为 LanguageDTO
.
我认为它不可行:Spring 仅支持 application.yaml 文件中的简单 属性 占位符(据我所知)。不过,您可以做的是利用 YAML 格式 built-in 功能,anchors and aliases:
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
For it to work, the
LanguageDTO
class needs to have setters and a default constructor. @AllArgsConstructor won't work. Alternatively you might try to get it work in conjunction with constructor binding, although I'm not sure if it's possible.