来自Typesafe配置的案例类实例化

Ram*_*gil 9 scala typesafe-config hocon

假设我有一个scala案例类,可以序列化为json(使用json4s或其他一些库):

case class Weather(zip : String, temp : Double, isRaining : Boolean)
Run Code Online (Sandbox Code Playgroud)

如果我正在使用HOCON配置文件:

allWeather {

   BeverlyHills {
    zip : 90210
    temp : 75.0
    isRaining : false
  }

  Cambridge {
    zip : 10013
    temp : 32.0
    isRainging : true
  }

}
Run Code Online (Sandbox Code Playgroud)

有没有办法使用typesafe配置来自动实例化Weather对象?

我正在寻找形式的东西

val config : Config = ConfigFactory.parseFile(new java.io.File("weather.conf"))

val bevHills : Weather = config.getObject("allWeather.BeverlyHills").as[Weather]
Run Code Online (Sandbox Code Playgroud)

该解决方案可以利用引用的值"allWeather.BeverlyHills"是json"blob" 的事实.

我显然可以编写自己的解析器:

def configToWeather(config : Config) = 
  Weather(config.getString("zip"), 
          config.getDouble("temp"), 
          config.getBoolean("isRaining"))

val bevHills = configToWeather(config.getConfig("allWeather.BeverlyHills"))
Run Code Online (Sandbox Code Playgroud)

但这似乎不够优雅,因为天气定义的任何变化也需要改变configToWeather.

提前感谢您的审核和回复.

Naz*_*iuk 11

typesafe配置库具有API,用于从使用java bean约定的配置中实例化对象.但据我所知,案例类不遵循这些规则.

几个scala库包装了typesafe配置并提供了您正在寻找的scala特定功能.

例如,使用pureconfig读取配置可能看起来像

val weather:Try[Weather] = loadConfig[Weather]
Run Code Online (Sandbox Code Playgroud)

其中Weather是config中值的case类

  • +1 为纯配置。熟悉 Spring Boot 优秀的【配置管理】(https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html),pureconfig 是关闭的东西我可以在 Scala 中找到。 (2认同)

Ram*_*gil 7

扩展Nazarii的答案,以下内容对我有用:

import scala.beans.BeanProperty

//The @BeanProperty and var are both necessary
case class Weather(@BeanProperty var zip : String,
                   @BeanProperty var temp : Double,
                   @BeanProperty var isRaining : Boolean) {

  //needed by configfactory to conform to java bean standard
  def this() = this("", 0.0, false)
}

import com.typesafe.config.ConfigFactory

val config = ConfigFactory.parseFile(new java.io.File("allWeather.conf"))

import com.typesafe.config.ConfigBeanFactory

val bevHills = 
  ConfigBeanFactory.create(config.getConfig("allWeather.BeverlyHills"), classOf[Weather])
Run Code Online (Sandbox Code Playgroud)

  • 请注意,所有三个无参数构造函数,`@BeanPropery` 和 `var` 都需要完成这项工作。如果你忘记了 `var`,你会默默地得到一个空值(在构造函数中分配)而不是配置的值。 (2认同)