如何解决列出Spring Boot中的分布式属性
下面的代码示例来自一个Spring Boot应用程序,该应用程序从本地application.properties文件获取属性定义。可从远程Consul服务器获得其他或覆盖的属性定义。目的是使应用程序枚举所有属性定义,而不管其来源如何。设置示例:
本地application.properties文件包含此属性定义 spring.cloud.stream.bindings.breakoutOutputChannel.destination = breakout_topic_local
Consul服务器中相同属性的主要定义是: spring.cloud.stream.bindings.breakoutOutputChannel.destination = breakout_topic_production
在同一代码中,我使用两种机制来访问相同的属性值。首先是使用@Value批注,其次是查询从环境获得的属性。获取应用程序环境属性的方法也如下所示。
使用@Value批注时,将获得正确的覆盖值。但是,当直接访问属性定义时,仅本地文件中的值可用。示例如下。
是否可以获得与@Value注释使用的属性相同的Map,以便可以枚举其内容?
示例代码:
@Value("${spring.cloud.stream.bindings.breakoutOutputChannel.destination}")
String breakout;
@EventListener
public void onApplicationEvent(ApplicationReadyEvent event) {
Properties props =applicationProperties(event.getApplicationContext().getEnvironment());
log.info("Property spring.cloud.stream.bindings.breakoutOutputChannel.destination");
log.info( " value from bound var = " +breakout);
log.info( " value from properties = " +props.getProperty("spring.cloud.stream.bindings.breakoutOutputChannel.destination"));
}
public Properties applicationProperties(Environment env) {
final Properties properties = new Properties();
for(Iterator it = ((AbstractEnvironment) env).getPropertySources().iterator(); it.hasNext(); ) {
PropertySource propertySource = (PropertySource) it.next();
if (propertySource instanceof PropertiesPropertySource) {
log.info("Adding all properties contained in " + propertySource.getName());
properties.putAll(((MapPropertySource) propertySource).getSource());
}
if (propertySource instanceof CompositePropertySource){
properties.putAll(getPropertiesInCompositePropertySource((CompositePropertySource) propertySource));
}
}
return properties;
}
private Properties getPropertiesInCompositePropertySource(CompositePropertySource compositePropertySource){
final Properties properties = new Properties();
compositePropertySource.getPropertySources().forEach(propertySource -> {
if (propertySource instanceof MapPropertySource) {
log.info("Adding all properties contained in " + propertySource.getName());
properties.putAll(((MapPropertySource) propertySource).getSource());
}
if (propertySource instanceof CompositePropertySource)
properties.putAll(getPropertiesInCompositePropertySource((CompositePropertySource) propertySource));
});
return properties;
}
样本输出
Adding all properties contained in applicationConfig: [file:./application.properties]
Adding all properties contained in applicationConfig: [classpath:/application.properties]
Property spring.cloud.stream.bindings.breakoutOutputChannel.destination
value from bound var = breakout_topic_production
value from properties = breakout_topic_local
解决方法
在上面的示例中创建的生成的属性对象的来源是应用程序环境,而这些值的确仅是包含在本地属性定义文件中的那些值。
但是,如果使用属性键直接从环境中获取值,则返回的值将包含从Consul分发给应用程序的任何替代。在示例中,返回值来自
event.getApplicationContext().getEnvironment().getProperty("spring.cloud.stream.bindings.breakoutOutputChannel.destination"));
将返回正确的属性值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。