You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot运行时如何编程式读取指定profile的配置属性

Spring Boot 2.7 运行时动态读取指定Profile配置的实现方式

Spring Boot 2.7.x 原生支持编程式读取指定profile的专属配置,不需要在应用启动时就固定激活的profile,完全可以满足Shell类应用动态根据命令参数加载对应环境配置的需求。

默认情况下Spring Boot启动时只会把当前激活profile对应的配置文件加载到上下文中,如果你启动时没有激活dev、prod这类环境,对应配置文件默认不会进入Environment,针对你要执行init --stage dev时动态读取对应配置的场景,有两种成熟的实现方式,按需选择即可。


方案1:按需加载指定profile配置(最适合交互式Shell场景)

这个方案不会修改主上下文的全局激活profile,不会导致不同命令之间的配置污染,完全匹配你执行单条命令时临时读取对应环境配置的需求。
Spring Boot 内部解析yml配置用的YamlPropertySourceLoader是公共类,可以直接拿来用,不用自己写yaml解析逻辑,也不需要额外引入依赖。

你可以写一个通用的配置加载组件,示例代码:

import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.List;

@Component
public class ProfileConfigLoader {
    private final YamlPropertySourceLoader yamlLoader = new YamlPropertySourceLoader();

    /**
     * 读取指定profile配置文件中的属性值
     * @param profile 环境标识 如dev/prod/local
     * @param configKey 配置键 如spring.datasource.url
     * @param targetType 配置值的目标类型
     */
    public <T> T getConfig(String profile, String configKey, Class<T> targetType) throws IOException {
        Resource configResource = new ClassPathResource(String.format("application-%s.yml", profile));
        if (!configResource.exists()) {
            throw new IllegalArgumentException("对应环境的配置文件不存在: " + profile);
        }
        List<PropertySource<?>> propertySources = yamlLoader.load("customProfile:" + profile, configResource);
        for (PropertySource<?> source : propertySources) {
            Object value = source.getProperty(configKey);
            if (value != null) {
                return ConversionService.getSharedInstance().convert(value, targetType);
            }
        }
        return null;
    }
}

调用方式非常简单:在init命令的处理逻辑里拿到--stage传入的环境标识后,直接调用这个组件的方法,就能拿到对应application-{stage}.yml里的任意配置值,Spring自带的类型转换工具会自动处理字符串、数字、列表等常见类型的转换,不用自己手写类型转换逻辑。


方案2:全局切换激活profile(适合单次执行的命令行应用)

如果你不止要读取配置,还要根据传入的环境参数加载对应@Profile标记的Bean,可以直接通过ConfigurableEnvironment动态修改激活的profile。

注意:这个方式会修改整个Spring上下文的全局配置,如果是常驻的交互式Shell应用不要用,会导致不同命令执行时配置互相干扰;如果是启动后只执行单条命令就退出的应用可以放心用。

核心代码示例:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;

@Component
public class ProfileSwitcher {
    @Autowired
    private ConfigurableEnvironment environment;
    @Autowired(required = false)
    private ConfigurationPropertiesRebinder rebinder;

    public void switchActiveProfile(String profile) {
        environment.setActiveProfiles(profile);
        // 如果用了@ConfigurationProperties绑定配置类,需要刷新绑定值
        if (rebinder != null) {
            rebinder.rebind();
        }
    }
}

ConfigurationPropertiesRebinder类在spring-cloud-context依赖中,Spring Boot 2.7.x 适配2021.0.x版本的Spring Cloud即可。


注意事项

  • 不要自己手写Yaml解析逻辑读配置文件,Spring自带的加载器会自动处理配置覆盖、占位符解析、嵌套结构等逻辑,自己写很容易踩占位符不生效、配置优先级错乱的坑
  • 如果你的profile配置里用了spring.profiles.include引入其他配置文件,方案1的基础实现不会自动加载被引入的配置,有这种需求可以单独用SpringApplicationBuilder构建一个轻量的子上下文,指定激活对应profile后读取配置,读完直接关闭子上下文即可,不会影响主上下文
  • 所有application-*.yml都会被打包到应用的classpath下,和启动时设置的激活profile无关,不用担心运行时找不到对应配置文件的问题

内容的提问来源于stack exchange,提问作者Robert Strauch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:57:52