Scala:使用PureConfig创建通用工具

时间:2019-04-24 03:15:51

标签: scala pureconfig

我正在Scala中寻找一些适合akka的实用程序,它们可以将HOCON映射到Scala类/对象。 (类似于Spring中的@Configuration,将.yml.properties文件映射到Configuration Bean / Java类。)

我对PureConfig所做的尝试:

资源中的

spark.conf配置文件

spark{
    master {
        host = 1.2.3.4
        port = 7077
    }
}

映射到以下scala类:

trait Configuration {
    val nameSpace: String
}

case class SparkConfig(master: SparkMasterConfig) extends Configuration {
    override val nameSpace: String = "spark"
}

case class SparkMasterConfig(host: String,
                                    port: Int)

PureConfig在没有泛型的情况下可以正常工作

import pureconfig.generic.auto._
import com.typesafe.config.ConfigFactory

val conf = ConfigFactory.parseResources("spark.conf")
val sparkConfig = pureconfig.loadConfig[SparkConfig]("spark")

val config = sparkConfig match {
    case Left(f) => fail(f.toString)
    case Right(c) => c
}

但是,以下通用util甚至不使用not enough arguments for method error

进行编译
object PureConfigLoader{
    def load[T <: Configuration](clazz: Class[T]): T = {
        val nameSpace = clazz.getField("nameSpace").get().asInstanceOf[String]

        import pureconfig.generic.auto._
        val configResult = pureconfig.loadConfig[T](nameSpace)  // this doesn't compile

        configResult match {
            case Right(x) => x.asInstanceOf[T]
            case Left(x) => throw new IllegalArgumentException(s"Fail to parse ${clazz.getSimpleName} from namespace $nameSpace")
        }
    }
}

val config = PureConfigLoader.load(classOf[SparkConfig])

我的问题是:

  1. 该通用PureConfig实用程序怎么办?
  2. import pureconfig.generic.auto._始终被IntelliJ标记为未使用的导入,并且在格式化我的代码时将其删除,如何解决此问题?
  3. 是否有其他类似的配置工具/库可以正常工作?我也尝试过circe-config,但仍然遇到类似的问题。 Simple Scala Config使用Scala的Dynamic,它不适用于重构,例如重命名配置属性字段。

谢谢

1 个答案:

答案 0 :(得分:2)

我使用Typesafe config的小包装:

https://github.com/kxbmap/configs

我尝试了您的示例-编译如下:

  object PureConfigLoader{
    def load[T <: MyConfig[T]](clazz: Class[T])(implicit A: Configs[T]): T = {
      val nameSpace = clazz.getField("nameSpace").get().asInstanceOf[String]

      val config = ConfigFactory.load("spark.conf")
        Configs[T].get(config, nameSpace) 
          .valueOrThrow(e=>
             new IllegalArgumentException(s"Fail to parse ${clazz.getSimpleName} from namespace $nameSpace: ${e.messages}" 
          )
      )
    }
  }

  val sparkConfig = PureConfigLoader.load(classOf[SparkConfig])

  abstract class MyConfig[T] (implicit A: Configs[T])

  case class SparkConfig() extends MyConfig[SparkConfig]

更新

我只是在我们的代码中看到您可能完全根本不需要此Util类!我们使用:

val config = ConfigFactory.load("spark.conf")
val sparkConfig = Configs[SparkConfig].get(config, nameSpace)