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

除了使用类继承,还有没有其他优雅的方式对不同环境进行配置管理呢?答案是有的,那就是 lightbend/config 中提到的方法,利用嵌套字典,使用 dev, test 等隔离子空间,配合默认根空间共享同样的配置项。核心代码如下所示:

import System.{getenv, getProperty}
import com.typesafe.config.ConfigFactory
import com.typesafe.config.{Config => TypesafeConfig}

/**
  * Created by yuanbin on 2018/2/26.
  */
object Config {
  private val originalConfig = ConfigFactory.load()
  val appEnv: String = Option(getProperty("APP_ENV")).getOrElse(getenv("APP_ENV")) match {
    case s: String => s
    case _ => {
      println("APP_ENV is not set in both environment and properties!!!")
      sys.exit(1)
    }
  }
  val conf: TypesafeConfig = originalConfig.getConfig(appEnv).withFallback(originalConfig)
}

上述代码中优先从 JVM 系统变量中读取 APP_ENV, 其次从环境变量中读取,读取后默认使用 appEnv 下的子空间变量,如若未找到则从共享的根空间读取。