我是 Scala 的新手,刚开始使用我的第一个 Scala 应用程序。
我已经在资源文件夹 application.conf 下定义了我的配置文件
projectname{
"application" {
"host":127.0.0.1
"port":8080
}
}
Run Code Online (Sandbox Code Playgroud)
我写了一个配置解析器文件来从配置文件解析到案例类
case class AppConfig (config: Config) {
val host = config.getString("projectname.application.host")
val port = config.getInt("projectname.application.port")
}
Run Code Online (Sandbox Code Playgroud)
在我的 grpc 服务器文件中,我已将配置声明为
val config = AppConfig(ConfigFactory.load("application.conf"))
Run Code Online (Sandbox Code Playgroud)
我想在整个应用程序中使用这个配置变量,而不是每次都加载 application.conf 文件。
我想要一个引导程序功能,它将解析此配置一次,使其在整个应用程序中可用
您可以使用PureConfig自动执行此操作。
build.sbt使用以下命令为您添加 Pure Config :
libraryDependencies += "com.github.pureconfig" %% "pureconfig" % "0.11.0"
Run Code Online (Sandbox Code Playgroud)
并重新加载 sbt shell 并更新您的依赖项。
现在,假设您有以下resource.conf文件:
host: example.com
port: 80
user: admin
password: admin_password
Run Code Online (Sandbox Code Playgroud)
您可以定义一个名为 的案例类AppConfig:
host: example.com
port: 80
user: admin
password: admin_password
Run Code Online (Sandbox Code Playgroud)
并使用以下loadConfig方法创建它的一个实例,填充应用程序配置:
case class AppConfig(
host: String,
port: Int,
user: String,
password: String
)
Run Code Online (Sandbox Code Playgroud)
这将返回错误或您的 AppConfig,具体取决于配置本身的值。
例如,如果port上面的值是eighty,而不是 80,你会得到一个详细的错误,说第二个配置行(带有port: eighty)包含一个字符串,但唯一有效的预期类型是一个数字:
ConfigReaderFailures(
ConvertFailure(
reason = WrongType(
foundType = STRING,
expectedTypes = Set(NUMBER)
),
location = Some(
ConfigValueLocation(
new URL("file:~/repos/example-project/target/scala-2.12/classes/application.conf"),
lineNumber = 2
)
),
path = "port"
)
)
Run Code Online (Sandbox Code Playgroud)
loadConfigOrThrow如果你想得到AppConfig而不是一个,你可以使用。
在应用程序开始时(尽可能接近主函数)加载此配置后,您可以使用依赖注入将其传递给所有其他类,只需在构造函数中传递 AppConfig 即可。
如果您想使用MacWire将您的 Logic 类(和其他服务)与配置案例类连接起来,正如 Krzysztof 在他的选项之一中建议的那样,您可以在此处查看我的答案。
简单的例子(没有MacWire),看起来像这样:
import pureconfig.generic.auto._
val errorsOrConfig: Either[ConfigReaderFailures, AppConfig] = pureconfig.loadConfig[AppConfig]
Run Code Online (Sandbox Code Playgroud)
其中 AppConfig 定义在 AppConfig.scala
ConfigReaderFailures(
ConvertFailure(
reason = WrongType(
foundType = STRING,
expectedTypes = Set(NUMBER)
),
location = Some(
ConfigValueLocation(
new URL("file:~/repos/example-project/target/scala-2.12/classes/application.conf"),
lineNumber = 2
)
),
path = "port"
)
)
Run Code Online (Sandbox Code Playgroud)
作为奖励,当您在 IDE 中使用此配置变量时,您将获得代码完成。
此外,您的配置可以从支持的类型构建,例如 String、Boolean、Int 等,但也可以从从支持的类型构建的其他案例类(这是因为案例类表示一个值对象,其中包含数据),以及支持类型的列表和选项。
这允许您“分类”一个复杂的配置文件并获得代码完成。例如,在application.conf:
name: hotels_best_dishes
host: "https://example.com"
port: 80
hotels: [
"Club Hotel Lutraky Greece",
"Four Seasons",
"Ritz",
"Waldorf Astoria"
]
min-duration: 2 days
currency-by-location {
us = usd
england = gbp
il = nis
}
accepted-currency: [usd, gbp, nis]
application-id: 00112233-4455-6677-8899-aabbccddeeff
ssh-directory: /home/whoever/.ssh
developer: {
name: alice,
age: 20
}
Run Code Online (Sandbox Code Playgroud)
然后在您的代码中定义一个配置案例类:
package com.example
import com.example.config.AppConfig
object HelloWorld extends App {
val config: AppConfig = pureconfig.loadConfigOrThrow[AppConfig]
val logic = new Logic(config)
}
class Logic(config: AppConfig) {
// do something with config
}
Run Code Online (Sandbox Code Playgroud)
并加载它:
package com.example.config
case class AppConfig(
host: String,
port: Int,
user: String,
password: String
)
Run Code Online (Sandbox Code Playgroud)