在 Spring Boot 中的 Yaml 中转义 Map 键中的点
Posted
技术标签:
【中文标题】在 Spring Boot 中的 Yaml 中转义 Map 键中的点【英文标题】:Escaping a dot in a Map key in Yaml in Spring Boot 【发布时间】:2016-03-08 08:40:42 【问题描述】:我有以下 yml 配置:
foo:
bar.com:
a: b
baz.com:
a: c
Spring 尝试通过以下类注入带有键 'bar' 和 'baz' 的映射,将点视为分隔符:
public class JavaBean
private Map<String, AnotherBean> foo;
(...)
我尝试引用密钥(即“bar.com”或“bar.com”)但无济于事 - 仍然是同样的问题。有没有办法解决这个问题?
【问题讨论】:
引用密钥没有帮助的原因是因为bar.com:
、"bar.com":
和'bar.com':
(和? bar.com
)在 YAML 中都代表相同的完全相同的东西,并且都被反序列化为字符串bar.com
。这个点在 YAML 中并不表示任何特殊的东西——你看到的行为是在 YAML 被反序列化后在 Spring 中发生的。
SPring 是在幕后使用 YamlPropertiesFactoryBean 吗?如果是这样,有没有办法让它使用 YamlMapFactoryBean 代替? :)
【参考方案1】:
对@fivetenwill 的回答稍作修改,在 Spring Boot 1.4.3.RELEASE 上对我有用:
foo:
"[bar.com]":
a: b
"[baz.com]":
a: c
您需要将括号放在引号内,否则 YAML 解析器基本上会在它们到达 Spring 之前将它们丢弃,并且它们不会使其成为属性名称。
【讨论】:
@shivakumar,直到 Spring Boot 2.1.7.RELEASE,这种方法仍然适用于我。除了查看Relaxed Binding 文档之外,不确定要向您建议什么,因为某些规则在 Spring Boot 2 中有所改变。另请参阅:Spring Boot 2 Migration Guide【参考方案2】:这应该可行:
foo:
"[bar.com]":
a: b
"[baz.com]":
a: c
灵感来自Spring Boot Configuration Binding Wiki
【讨论】:
【参考方案3】:如果您想将 yaml 键自动映射到 Java bean 属性,这是不可能的。原因是,Spring 首先将 YAML 转换为属性格式。 请参阅以下链接的第 24.6.1 节:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
所以,你的 YAML 被转换为:
foo.bar.com.a=b
foo.baz.com.a=c
上面的键被解析为标准属性。
作为一种变通方法,您可以使用 Spring 的 YamlMapFactoryBean
按原样创建 Yaml 映射。然后,您可以使用该映射来自己创建 Java bean。
@Configuration
public class Config
private Map<String, Object> foo;
@Bean
public Map<String, Object> setup()
foo = yamlFactory().getObject();
System.out.println(foo); //Prints foo=bar.com=a=b, baz.com=a=c
return foo;
@Bean
public YamlMapFactoryBean yamlFactory()
YamlMapFactoryBean factory = new YamlMapFactoryBean();
factory.setResources(resource());
return factory;
public Resource resource()
return new ClassPathResource("a.yaml"); //a.yaml contains your yaml config in question
【讨论】:
有什么方法可以让 YamlMapFactoryBean 返回某个 Bean 实例的映射而不是映射的映射?有什么方法可以从特定配置节点返回地图?我的 yml 更复杂,地图配置只是其中的一部分,我宁愿不将地图配置分开到单独的配置。上面的代码对我来说已经够hackish了:) 我同意你的看法。上面的代码需要解决一些问题。但是为了最大限度地利用 spring 自动配置,我担心你将不得不放弃 yaml 键中的点。否则,在上面的 setup() 方法中,您可以迭代 yaml 对象并手动创建 bean(这可能会导致自动装配问题)。 是的,我明白了。我仍然会尝试查找 Spring 是如何自动装配的,也许有一种方法可以让它从地图而不是属性自动装配:)以上是关于在 Spring Boot 中的 Yaml 中转义 Map 键中的点的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AWS CloudFormation YAML 模板中转义策略变量
将 YAML 列表映射到 Spring Boot 中的对象列表
Spring Boot2 系列教程理解Spring Boot 配置文件 application.properties