在前文 Python 多环境配置类 中提过可以使用类继承的方式管理开发、测试和生产环境的配置,简洁优雅。相较于动态语言 Python 而言,Scala/Java 使用同样的思路来实现多环境配置管理则蹩脚的多。故传统 Java 开发中常采用dev, prod 等不同后缀名的配置文件对不同环境进行区分,也算简单实用,只是不可避免会存在一些重复配置项。

除了使用类继承,还有没有其他优雅的方式对不同环境进行配置管理呢?答案是有的,那就是 lightbend/config 中提到的方法,利用嵌套字典,使用 dev, test 等隔离子空间,或者使用单独的配置文件隔离,配合默认根空间共享同样的配置项。完整的使用方式可见测试类 AppConfigFactoryTest.java

核心代码如下所示:

public class AppConfigFactoryTest {

    @Test
    public void testConfig() {
        Config config = AppConfigFactory.load();
        assertEquals("ci.yuanbin.me", config.getString("common.host"));
        assertEquals(8080, config.getInt("common.port"));
        assertEquals("ci", config.getString("app.profiles.active"));
    }

    @Test
    public void testSingleton() {
        Config config1 = AppConfigFactory.load();
        Config config2 = AppConfigFactory.load();
        assert config1 == config2;
    }
}

上述代码中优先从 JVM 系统变量中读取 APP_PROFILES_ACTIVE, 其次从环境变量中读取。AppConfigFactory.load() 为单例实现,赌赢环境变量的配置文件内容会覆盖默认的 application.conf 中的内容。

这里的 AppConfigFactory.load() 相对于 TypesafeConfig 新增了多环境配置文件的选择,并且可以通过 APP_PROFILES_ACTIVE 控制。