【问题标题】:Scala: Creating generic util with PureConfigScala:使用 PureConfig 创建通用实用程序
【发布时间】:2019-09-13 06:27:27
【问题描述】:

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

我对@9​​87654322@ 的尝试:

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
}

但是,以下通用工具甚至无法使用 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 不利于重构,例如重命名配置属性字段。

谢谢

【问题讨论】:

    标签: scala pureconfig


    【解决方案1】:

    我使用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) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-12
      • 2022-01-22
      • 2015-07-06
      • 1970-01-01
      • 2017-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多