spring.profiles.active=dev,mysql,即激活多Profile应用启动失败

Blade 未结 1 215
tangjiali
tangjiali 剑童 2023-07-07 09:49

以下源码涉及bladex-tool下的blade-core-launch模块的BladeApplication类。


一、该问题的重现步骤是什么?

1. 设置`spring.profiles.active=dev,mysql`;

2. 启动应用。


二、你期待的结果是什么?实际看到的又是什么?

期望是应用能够激活dev和mysql两个Profile,但实际会报错:

同时存在环境变量:[dev,mysql]


三、你正在使用的是什么产品,什么版本?在什么操作系统上?

Bladex 3.1.1.RELEASE


四、请提供详细的错误堆栈信息,这很重要。


五、若有更多详细信息,请在下面提供。

// 拿到全部激活Profile,dev,mysql
String[] activeProfiles = environment.getActiveProfiles();

// 转list,dev,mysql
List<String> profiles = Arrays.asList(activeProfiles);
// 预设三种环境
List<String> presetProfiles = new ArrayList(Arrays.asList("dev", "test", "prod"));
// 取交集后,presetProfiles只剩dev,profiles还是dev,mysql
presetProfiles.retainAll(profiles);

// 激活的profile,dev,mysql
List<String> activeProfileList = new ArrayList(profiles);
Function<Object[], String> joinFun = StringUtils::arrayToCommaDelimitedString;
SpringApplicationBuilder builder = new SpringApplicationBuilder(new Class[]{source});
String profile;

if (activeProfileList.isEmpty()) {
    // 激活的Profile不为空,不走此分支
    profile = "dev";
    activeProfileList.add(profile);
    builder.profiles(new String[]{profile});
} else {
    if (activeProfileList.size() != 1) {
        // 激活的Profile不是1个,命中抛异常
        throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]");
    }

    profile = (String)activeProfileList.get(0);
}


我理解框架应该是支持这种激活多Profile的,但是激活的多个Profile只能有一个是预设的Profile,也就是最多只能由dev、test、prod中的一个,至于其它非预设的Profile则没有限制。


因此我尝试做如下改写:

// 获取配置的环境变量
String[] activeProfiles = environment.getActiveProfiles();
// 判断环境:dev、test、prod
List<String> profiles = Arrays.asList(activeProfiles);
// 预设的环境
List<String> presetProfiles = new ArrayList<>(Arrays.asList(AppConstant.DEV_CODE, AppConstant.TEST_CODE, AppConstant.PROD_CODE));
// 交集
presetProfiles.retainAll(profiles);
// 当前使用
List<String> activeProfileList = new ArrayList<>(profiles);
Function<Object[], String> joinFun = StringUtils::arrayToCommaDelimitedString;

// 开始改写
Function<List<String>, String[]> toArray = (list) -> {
   String[] result = new String[list.size()];
   list.toArray(result);
   return result;
};

SpringApplicationBuilder builder = new SpringApplicationBuilder(source);
String profile;
if (presetProfiles.isEmpty()) {
   // 没有指定任何一个预设的Profile,默认加入dev
   profile = AppConstant.DEV_CODE;
   activeProfileList.add(profile);
} else if (presetProfiles.size() == 1) {
   profile = activeProfileList.get(0);
} else {
   // 同时存在dev、test、prod环境时
   throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(toArray.apply(presetProfiles)) + "]");
}

// 设置全部激活Profile,以下二选一即可
builder.profiles(toArray.apply(activeProfileList));
props.setProperty("spring.profiles.active", joinFun.apply(toArray.apply(activeProfileList)));




1条回答
  • blade.env只能指定一个。

    {WVM1K)U@_32[[1FAG7A13M.png

    如果有新环境的配置文件,这里也要新建一个新环境的日志配置文件。

    _)W%1P$D_9GM[@BXMC)HSJG.png

    作者追问:2023-07-07 10:13

    问题不在这里,我的改动也不会改变blade.env只能有一个的逻辑,且blade.env还是只能是dev、test、prod中的一个。


    但有时我们可以把某部分配置另外放一个配置文件,比如我们有application-dev.yaml的同时,我们把数据库连接的配置放在另一个文件application-mysql.yaml中。正常Spring Boot应用可以通过spring.profiles.active=dev,mysql激活两个配置文件,参见Spring Boot Profiles


    image.png






    0 讨论(0)
提交回复