使用环境覆盖 Spring Cloud Config 值

Posted

技术标签:

【中文标题】使用环境覆盖 Spring Cloud Config 值【英文标题】:Override Spring Cloud Config values with environment 【发布时间】:2015-10-11 14:45:07 【问题描述】:

有没有办法用另一个属性源(特别是系统环境)覆盖通过 Spring Cloud Config Server 设置的属性?我知道我可以通过循环遍历Environment 对象的PropertySources 来手动执行此操作,但如果我可以将其设置为bootstrapConfig 源的优先级最低,那将是理想的。

【问题讨论】:

您有没有找到一种无需编写自己的应用程序侦听器就能做到这一点的方法? 不,没有其他方法可以做到这一点,至少在 Spring Boot 1.2.x 中没有。我还没有检查 1.3.x (Spring Cloud Brixton)。 【参考方案1】:

FWIW,我通过编写自定义 ApplicationListener 来完成此操作,其事件在周期早期触发,但在加载配置服务的 PropertySource 之后。我在这里附上了代码,以防有人感兴趣。如果有一种“官方”的 Spring 方式可以做到这一点,我仍然很感兴趣,但这有效:

package com.example;

import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

@Order(Ordered.HIGHEST_PRECEDENCE)
public class ConfigServicePropertyDeprioritizer
        implements ApplicationListener<ApplicationPreparedEvent>

    private static final String CONFIG_SOURCE = "bootstrap";

    private static final String PRIORITY_SOURCE = "systemEnvironment";

    @Override
    public void onApplicationEvent(ApplicationPreparedEvent event)
    
        ConfigurableEnvironment environment = event.getApplicationContext()
                .getEnvironment();
        MutablePropertySources sources = environment.getPropertySources();
        PropertySource<?> bootstrap = findSourceToMove(sources);

        if (bootstrap != null)
        
            sources.addAfter(PRIORITY_SOURCE, bootstrap);
        
    

    private PropertySource<?> findSourceToMove(MutablePropertySources sources)
    
        boolean foundPrioritySource = false;

        for (PropertySource<?> source : sources)
        
            if (PRIORITY_SOURCE.equals(source.getName()))
            
                foundPrioritySource = true;
                continue;
            

            if (CONFIG_SOURCE.equals(source.getName()))
            
                // during bootstrapping, the "bootstrap" PropertySource
                // is a simple MapPropertySource, which we don't want to
                // use, as it's eventually removed. The real values will 
                // be in a CompositePropertySource
                if (source instanceof CompositePropertySource)
                
                    return foundPrioritySource ? null : source;
                
            
        

        return null;
    

【讨论】:

以上是关于使用环境覆盖 Spring Cloud Config 值的主要内容,如果未能解决你的问题,请参考以下文章

spring cloud config如何使用本地属性覆盖远程属性

spring-cloud-consul:无法覆盖 ConsulProperties 中的默认值

Spring Cloud 数据流 - 休息客户端 - 覆盖 RestTemplate

用本地属性覆盖远程 Spring Cloud 属性

Spring Cloud Config分布式配置中心的使用和遇到的坑

spring-cloud-square开发实战(三种类型全覆盖)