hoplite

2025-12-11 0 571

hoplite

hoplite是一个Kotlin库,用于以无样板方式将配置文件加载到TypeAfe类中。使用Kotlin数据类定义您的配置,在启动时, hoplite将从一个或多个配置文件中读取,将这些文件中的值映射到您的配置类中。任何丢失的值或无法转换为所需类型的值都会导致配置失败,并使用详细的错误消息。

特征

  • 多种格式以几种格式编写配置:YAML,JSON,TOML,HOCON或JAVA .props Files,甚至在同一系统中混合和匹配格式。
  • 属性来源:从JVM系统属性,环境变量,JNDI或每个用户本地配置文件中可以使用每现在系统替代。
  • 电池包括:对许多标准类型的支持,例如原始类型,枚举,日期,收集类型,内联类,UUID,无效类型,以及受欢迎的Kotlin第三方库类型,例如NonEmptyListOptionTupleX来自Arrow。
  • 自定义数据类型: Decoder接口使您可以轻松地添加对您的自定义域类型或未介绍的标准库类型的支持。
  • 级联:配置文件可以堆叠。从默认文件开始,然后在顶部将新配置层层。解决配置时,值的查找落在包含定义的第一个文件中。可以用来具有默认配置文件,然后使用特定于环境的文件。
  • 美丽的错误:在运行时失败,出现了精美的错误,显示出了什么出了什么问题和位置。
  • 预处理程序:支持几个预处理程序,这些预处理器将用从外部配置解决的值替换占位符,例如AWS Secrets Manager,Azure KeyVault等。
  • 可重新加载配置:触发配置重新加载在固定的间隔或响应外部事件(例如领事价值更改)时。
  • 前缀绑定:可选地,加载配置源一次,然后将单个前缀路径绑定到独立的配置类型中。

ChangElog

请参阅此处的每个版本中的更改列表。

入门

将hoplite添加到您的构建中:

hoplite -core:<version>\’\”>

implementation \' com.sksamuel. hoplite : hoplite -core:<version> \'

您还需要包含用于使用格式的模块。

接下来定义将包含配置的数据类。您应该创建一个可以简单地命名Config或ProjectNameConfig的顶级类。然后,此类为您需要的每个配置值定义一个字段。它可以包括用于将相关配置分组的嵌套数据类。

例如,如果我们有一个需要数据库配置的项目,嵌入式HTTP服务器的配置以及一个包含我们正在运行的环境(登台,QA,生产等)的字段,那么我们可能会定义这样的类:

 data class Database ( val host : String , val port : Int , val user : String , val pass : String )
data class Server ( val port : Int , val redirectUrl : String )
data class Config ( val env : String , val database : Database , val server : Server )

对于我们的登台环境,我们可能会创建一个称为application-staging.yaml YAML(或JSON等)文件。该名称无关紧要,您可以使用您想要的任何惯例。

 env : staging

database :
  host : staging.wibble.com
  port : 3306
  user : theboss
  pass : 0123abcd

server :
  port : 8080
  redirectUrl : /404.html

最后,要从此文件构建Config实例,并且假设配置文件在classPath上,我们可以简单地执行:

 val config = ConfigLoaderBuilder .default()
               .addResourceSource( \" /application-staging.yml \" )
               .build()
               .loadConfigOrThrow< Config >()

如果配置文件中的值兼容,则将返回Config实例。否则,将抛出一个例外,其中包含错误的详细信息。

配置加载程序

正如您从“入门指南”中看到的那样, ConfigLoader是使用hoplite入口点。我们通过ConfigLoaderBuilder Builder创建此加载程序类的实例。在此构建器中,我们添加资源,配置,启用报告,添加预处理器等。

要创建一个默认的构建器,请使用ConfigLoaderBuilder.default() ,然后添加源后,调用build 。这是一个示例:

 ConfigLoaderBuilder .default()
  .addResourceSource( \" /application-prod.yml \" )
  .addResourceSource( \" /reference.json \" )
  .build()
  .loadConfigOrThrow< MyConfig >()

ConfigLoaderBuilder上的default方法设置了建议的默认值。如果您想从一个完全空的配置构建器开始,请使用ConfigLoaderBuilder.empty()

有两种方法可以从配置检索填充的数据类。首先是如果无法解决配置,则提出异常。我们通过loadConfigOrThrow<T>函数来执行此操作。另一个是如果要手动处理错误,则通过loadConfig<T>函数返回ConfigResult验证单元。

在大多数情况下,当您在应用程序启动时解决配置时,基于异常的方法更好。这是因为您通常希望Config中的任何错误以中止应用程序引导程序,将错误立即转移到控制台上。

前缀结合

前缀可用于将选定的配置绑定到独立的数据类。这对于模块化配置加载很有用。例如,独立的模块或插件从一组共同的配置源加载自己的配置。

例如包含

 module1 :
  foo : bar

module2 :
  baz : qux

可以绑定到:

 data class Module1Config ( val foo : String )

data class Module2Config ( val baz : String )

最好的方法是从ConfigLoader获得ConfigBinder ,例如:

 val configBinder = ConfigLoaderBuilder .default()
  .addResourceSource( \" /application-prod.yml \" )
  .addResourceSource( \" /reference.json \" )
  .build()
  .configBinder()

// generally a ConfigBinder will be provided via DI, and these calls will be in their own modules!
val module1Config = configBinder.bindOrThrow< Module1Config >( \" module1 \" )
val module2Config = configBinder.bindOrThrow< Module2Config >( \" module2 \" )

通过这种方法,配置源只能读取和解析一次,但可以绑定到必要的多次独立数据类。

如果只需要加载一个前缀,则还可以直接向loadConfig及其变体提供prefix

prefix值不必仅参考root属性foo.bar的前缀将在配置ConfigLoader创建的配置树中的foo.bar节点上访问config。

美丽的错误

当确实发生错误时,如果选择抛出异常,则错误将以人为可读的方式以及尽可能多的位置信息进行格式化。不再尝试在400行配置文件中跟踪NumberFormatException

这是单位测试使用的测试文件的错误格式的示例。请注意,错误表示该值已从哪个文件中提取。

hoplite.json.Foo\’ because:

– \’bar\’: Required type Boolean could not be decoded from a Long (classpath:/error1.json:2:19)

– \’baz\’: Missing from config

– \’hostname\’: Type defined as not-null but null was loaded from config (classpath:/error1.json:6:18)

– \’season\’: Required a value for the Enum type com.sksamuel. hoplite .json.Season but given value was Fun (/home/user/default.json:8:18)

– \’users\’: Defined as a List but a Boolean cannot be converted to a collection (classpath:/error1.json:3:19)

– \’interval\’: Required type java.time.Duration could not be decoded from a String (classpath:/error1.json:7:26)

– \’nested\’: – Could not instantiate \’com.sksamuel. hoplite .json.Wibble\’ because:

– \’a\’: Required type java.time.LocalDateTime could not be decoded from a String (classpath:/error1.json:10:17)

– \’b\’: Unable to locate a decoder for java.time.LocalTime\”>

 Error loading config because:

    - Could not instantiate \'com.sksamuel. hoplite .json.Foo\' because:

        - \'bar\': Required type Boolean could not be decoded from a Long (classpath:/error1.json:2:19)

        - \'baz\': Missing from config

        - \'hostname\': Type defined as not-null but null was loaded from config (classpath:/error1.json:6:18)

        - \'season\': Required a value for the Enum type com.sksamuel. hoplite .json.Season but given value was Fun (/home/user/default.json:8:18)

        - \'users\': Defined as a List but a Boolean cannot be converted to a collection (classpath:/error1.json:3:19)

        - \'interval\': Required type java.time.Duration could not be decoded from a String (classpath:/error1.json:7:26)

        - \'nested\': - Could not instantiate \'com.sksamuel. hoplite .json.Wibble\' because:

            - \'a\': Required type java.time.LocalDateTime could not be decoded from a String (classpath:/error1.json:10:17)

            - \'b\': Unable to locate a decoder for java.time.LocalTime

支持格式

hoplite支持多种格式的配置文件。如果您真的愿意,您可以混合使用和匹配格式。对于要使用的每种格式,您必须在类路径上包含适当的hoplite模块。 hoplite用来解析文件的格式由文件扩展名确定。

格式 模块 文件扩展
JSON hoplite -json .json
YAML注意:YAML文件的大小有限3MB。 hoplite -yaml .yml,.yaml
汤姆 hoplite -toml .toml
Hocon hoplite -hocon .conf
Java属性文件 内置 .props,.properties

如果您想添加另一种格式,则可以扩展Parser并通过addParserConfigLoaderBuilder提供该实现的实例。

相同的功能可用于将非默认文件扩展映射到现有解析器。例如,如果您希望将您的config放在nater application.data中但以yaml格式中的config,则可以在这样的yaml解析器上注册.data:

ConfigLoaderBuilder.default().addParser(\"data\", YamlParser).build()

注意:Fatjar/Shadowjar

如果尝试在使用多个文件类型模块时构建“胖罐”,则必须使用ShadowJar插件并在Shadowjar Gradle任务中添加指令mergeServiceFiles() 。更多信息

物业来源

PropertySource接口是hoplite读取配置值的方式。

hoplite支持几种内置的属性源实现,您可以根据需要编写自己的文章。

EnvironmentVariablesPropertySourceSystemPropertiesPropertySourceUserSettingsPropertySourceXdgConfigPropertySource源将自动注册,并以该顺序为准。其他属性源可以根据需要将其传递给Config Loader Builder。

Environment VariablesPropertysource

EnvironmentVariablesPropertySource VariablesPropertySource从环境变量中读取配置。此属性源将环境变量名称映射到通过环境变量的惯用约定配置属性。 env var是惯用的大写,仅包含字母( AZ ),数字( 09 )和下划线( _ )字符。

hoplite Maps env vars如下:

  • 下划线是嵌套配置的分离器。例如, TOPIC_NAME将覆盖topic父母中的属性name

  • 要将env vars绑定到数组或列表,请使用索引的后缀EG SET env vars TOPIC_NAME_0TOPIC_NAME_1设置name列表属性的两个值。丢失的索引被忽略,这对于在不重新恢复后续值的情况下评论值很有用。

  • 要将env vars绑定到地图,键是嵌套配置EG TOPIC_NAME_FOO的一部分,而TOPIC_NAME_BAR将为name映射属性设置“ foo”和“ bar”键。请注意,键是惯用大写规则的一个例外 – env var名称确定地图密钥的情况。

如果提供了可选的(未指定) prefix设置,则仅考虑以前缀开头的ENV VAR,并且在处理之前将前缀从Env var中剥离。

从hoplite 3开始,默认情况下将应用EnvironmentVariablesPropertySource ,可用于直接覆盖其他配置属性。对config.override.前缀。但是,可选的prefix设置仍然可以用于相同的目的。

SystemPropertiesPropertysource

SystemPropertiesPropertySource通过config.override. 。例如,使用-Dconfig.override.database.name启动JVM将覆盖database.name驻留在文件中。

USERTESTINGSPROPERTYSOURCE

UserSettingsPropertySource通过在〜/.userconfig上定义的配置文件提供配置。[ext]其中ext是受支持的格式之一。

InputStreamPropertysource

InputStreamPropertySource提供来自输入流的配置。此源需要一个指示格式的参数。例如, InputStreamPropertySource(input, \"yml\")

configfilepropertysource

来自文件或资源的配置是通过ConfigFilePropertySource的实例检索的。当我们将字符串传递到loadConfigOrThrowloadConfig函数时,将自动添加此属性源。

ConfigLoaderBuilder上有便利的方法可以从类Path或文件上的资源中构造ConfigFilePropertySource s。

例如,以下是等效的:

 ConfigLoader ().loadConfigOrThrow< MyConfig >( \" /config.json \" )

 ConfigLoaderBuilder .default()
   .addResourceSource( \" /config.json \" )
   .build()
   .loadConfigOrThrow< MyConfig >()

第二种方法的优点是我们可以指定文件可以是可选的,例如:

 ConfigLoaderBuilder .default()
  .addResourceSource( \" /missing.yml \" , optional = true )
  .addResourceSource( \" /config.json \" )
  .build()
  .loadConfigOrThrow< MyConfig >()

JSONPROPERTYSOURCE

要使用JSON字符串作为属性源,我们可以使用JsonPropertySource实现。例如,

 ConfigLoaderBuilder .default()
   .addSource( JsonPropertySource ( \"\"\" { \"database\": \"localhost\", \"port\": 1234 } \"\"\" ))
   .build()
   .loadConfigOrThrow< MyConfig >()

YamlPropertysource

要使用YAML字符串作为属性源,我们可以使用YamlPropertySource实现。

 ConfigLoaderBuilder .default()
   .addSource( YamlPropertySource (
     \"\"\"
        database: \"localhost\"
        port: 1234
     \"\"\" ))
   .build()
   .loadConfigOrThrow< MyConfig >()

Tomlpropertysource

要使用TOML字符串作为属性源,我们可以使用TomlPropertySource实现。

 ConfigLoaderBuilder .default()
  .addSource( TomlPropertySource (
    \"\"\"
        database = \"localhost\"
        port = 1234
     \"\"\" ))
  .build()
  .loadConfigOrThrow< MyConfig >()

Propspropertysource

要使用java.util.properties对象作为属性源,我们可以使用PropsPropertySource实现。

 ConfigLoaderBuilder .default()
  .addSource( PropsPropertySource (myProps))
  .build()
  .loadConfigOrThrow< MyConfig >()

级联配置

hoplite具有级联或分层或后备配置的概念。这意味着您可以将多个配置文件传递给configloader。当配置分为Kotlin类中时,查找将以传递给加载程序的顺序级联或通过一个文件落入另一个文件,直到定义该密钥的第一个文件为止。

例如,如果您在yaml中有以下两个文件:

application.yaml

 elasticsearch :
  port : 9200
  clusterName : product-search

application-prod.yaml

 elasticsearch :
  host : prd-elasticsearch.scv
  port : 8200

两者都将两者都传递给了configloader: ConfigLoader().loadConfigOrThrow<Config>(\"/application-prod.yaml\", \"/application.yaml\") ,然后将以声明文件的顺序尝试查找。因此,在这种情况下,配置将像这样解决:

 elasticsearch.port = 8200 // the value in application-prod.yaml takes priority
elasticsearch.host = prd-elasticsearch.scv // only defined in application-prod.yaml
elasitcsearch.clusterName = product-search // only defined in application.yaml

让我们看看一个更复杂的例子。这次在Json。

default.json

{
  \"a\" : \" alice \" ,
  \"b\" : {
    \"c\" : true ,
    \"d\" : 123
  },
  \"e\" : [
    {
      \"x\" : 1 ,
      \"y\" : true
    },
    {
      \"x\" : 2 ,
      \"y\" : false
    }
  ],
  \"f\" : \" Fall \"
}

prod.json

{
  \"a\" : \" bob \" ,
  \"b\" : {
    \"d\" : 999
  },
  \"e\" : [
    {
      \"y\" : true
    }
  ]
}

我们将把上述配置文件解析到这些数据类中:

 enum class Season { Fall , Winter , Spring , Summer }
data class Foo ( val c : Boolean , val d : Int )
data class Bar ( val x : Int? , val y : Boolean )
data class Config ( val a : String , val b : Foo , val e : List < Bar >, val f : Season )
 val config = ConfigLoader .load( \" prod.json \" , \" default.json \" )
println (config)

决议规则如下:

  • 两个文件中都存在“ a”,因此从第一个文件解决 – 是“ prod.json”
  • 两个文件中都存在“ B”,因此也从文件中解决
  • “ c”是“ b”的嵌套值,并且不存在第一个文件中,因此从第二个文件“ default.json”中解析。
  • “ D”是两个文件中存在的“ b”的嵌套值,因此从第一个文件解决
  • 两个文件中都存在“ E”,因此整个列表从第一个文件解决。这意味着该列表仅包含一个元素,尽管第一个文件中的列表中存在,但X还是无效的。列表不能合并。
  • “ F”仅存在于第二个文件中,因此从第二个文件中解决。

严格模式

如果不使用配置值,则可以将hoplite配置为丢弃错误。这对于检测过时的配置很有用。

要启用此设置,请在配置构建器上使用.strict() 。例如:

 ConfigLoaderBuilder .default()
  .addResourceSource( \" /config-prd.yml \" , true )
  .addResourceSource( \" /config.yml \" )
  .strict()
  .build()
  .loadConfig< MyConfig >()

此输出的一个例子是:

 Error loading config because:

    Config value \'drop_drop\' at (classpath:/snake_case.yml:0:10) was unused

    Config value \'double_trouble\' at (/home/sam/.userconfig.yml:2:16) was unused

别名

如果您想重构配置类并重命名字段,但是您不想更新所有配置文件,则可以通过允许字段使用多个名称来添加迁移路径。为此,我们使用@configalias注释。

例如,使用此配置文件:

 database :
  host : String

我们可以将其纳入以下数据类。

 data class Database ( val host : String )
data class MyConfig ( val database : Database )

或者

 data class Database (@ConfigAlias( \" host \" ) val hostname : String )
data class MyConfig ( val database : Database )

参数映射器

hoplite提供了一个接口ParameterMapper ,该接口允许在配置源内查找参数名称之前对其进行修改。这允许hoplite找到与确切名称不匹配的配置键。这样做的主要用例是允许使用snake_casekebab-case名称作为配置键。

例如,给定以下配置类:

 data class Database ( val instanceHostName : String )

然后,我们当然可以定义我们的配置文件(以YML为例):

 database :
    instanceHostName : server1.prd

但是,由于hoplite会自动注册KebabCaseParamMapperSnakeCaseParamMapper ,因此我们可以同样容易使用:

 database :
  instance-host-name : server1.prd

或者

 database :
  instance_host_name : server1.prd 

解码器

hoplite使用Decoder接口的实例将配置文件中的原始值转换为JDK类型。在所有标准日常类型中,都有内置的解码器,例如原语,日期,列表,集合,地图,枚举,箭头类型等。完整列表如下:

基本JDK类型 转换笔记
String
Long
Int
Short
Byte
Boolean 从以下值创建一个布尔值: \"true\"\"t\"\"1\"\"yes\"映射到true\"false\"\"f\"\"0\"\"no\"映射到false
Double
Float
Enums Java和Kotlin枚举都得到了支持。将使用Config中给出的常数值创建定义的枚举类的实例。
BigDecimal 从字符串,长,int,double或浮动转换为bigdecimal
BigInteger 从长或int转换为biginteger。
UUID 用字符串创建一个java.util.UUID
Locale 从字符串中创建一个java.util.Locale
Java.Time类型
LocalDateTime
LocalDate
LocalTime
Duration 在持续时间或长度以毫秒的时间内从字符串中创建Java Duration
Instant 从Unix Epoc以毫秒为单位创建一个Instant实例。
Year 2007字符串中创建Year的实例
YearMonth 2007-12弦乐中创建一个YearMonth的实例
MonthDay 从格式08-18的字符串中创建MonthDay的实例
java.util.Date
Kotlin类型
Duration 在持续时间格式或长度以毫秒的长度中创建kotlin Duration
ByteArray 从字符串中创建一个Kotlin ByteArray
Java.net类型
URI
URL
InetAddress
JDK IO类型
File 从字符串路径创建Java.io.file
Path 从字符串路径创建Java.nio.Path
Kotlin Stdlib类型
Pair<A,B> 将三个阵列转换为Pair<A,B>的实例。如果数组没有两个元素,将会失败。
Triple<A,B,C> 从三个元素的数组转换为Triple<A,B,C>的实例。如果数组没有完全三个元素,将会失败。
kotlin.text.Regex 从正则兼容字符串中创建kotlin.text.Regex
收藏
List<A> 从逗号界定的数组或字符串中创建列表。
Set<A> 从逗号界定的数组或字符串中创建一个集合。
SortedSet<A> 从逗号界定的数组或字符串中创建排序集。
Map<K,V>
LinkedHashMap<K,V> 在配置中定义的订单的地图
hoplite类型
Masked 将字符串包裹在掩蔽的对象中,该对象编辑ToString()
SizeInBytes 返回一个sizeinbytes对象,该对象解析了诸如12MIB或9KB之类的值
Seconds 将整数用Seconds对象包装,可以使用.duration()扩展方法将其转换为持续时间。
Minutes 将整数包装在Minutes对象中,可以使用.duration()扩展方法将其转换为持续时间。
Base64 将一个ByteBufferBase64对象中,该对象仅在输入是有效的基本64编码字符串时才转换。
Javax.security.auth
X500Principal 为字符串值创建X500Principal的实例
KerberosPrincipal 为字符串值创建一个KerberosPrincipal的实例
JMXPrincipal 为字符串值创建JMXPrincipal的实例
Principal 为字符串值创建一个BasicPrincipal实例
需要hoplite -arrow模块
arrow.data.NonEmptyList<A> 如果数组不为空,则将数组转换为非NonEmptyList<A> 。如果数组为空,则会增加错误。
arrow.core.Option<A> 一个None用于null或未定义值,并且当前值将转换为Some<A>
arrow.core.Tuple2<A,B> 将两个元素的数组转换为Tuple2<A,B>的实例。如果数组没有两个元素,将会失败。
arrow.core.Tuple3<A,B,C> 将三个元素的数组转换为Tuple3<A,B,C>的实例。如果数组没有完全三个元素,将会失败。
arrow.core.Tuple4<A,B,C,D> 将四个元素的数组转换为Tuple4<A,B,C,D>的实例。如果数组没有四个元素,将会失败。
arrow.core.Tuple5<A,B,C,D,E> 将五个元素的数组转换为Tuple5<A,B,C,D,E>的实例。如果阵列没有五个元素,将会失败。
Hikari连接池 需要hoplite -hikaricp模块
HikariDataSource 将嵌套配置转换为HikariDataSource 。在创建数据源时,嵌套在字段名称下的任何键将传递到HikariConfig对象。需要hoplite -hikaricp模块
hadoop类型 需要hoplite -hdfs模块
org.apache.hadoop.fs.Path 返回HDFS路径对象的实例
Cronutils类型 需要hoplite -cronutils模块
com.cronutils.model.Cron 返回cron表达式解析的实例
Kotlinx DateTime类型 需要hoplite -datetime模块
kotlinx.datetime.LocalDateTime
kotlinx.datetime.LocalDate
kotlinx.datetime.Instant
AWS SDK类型 需要hoplite -aws模块
com.amazonaws.regions.Region
千分尺类型 需要hoplite -micrometer-xxx模块
io.micrometer.statsd.DatadogConfig 将嵌套对象转换为datadogconfig的实例
io.micrometer.statsd.PrometheusConfig 将嵌套对象转换为Prometheusconfig的实例
io.micrometer.statsd.StatsdConfig 将嵌套对象转换为StatsdConfig的实例

持续时间格式

持续时间类型支持以下格式的单元字符串(仅较低的情况),单位值和单位类型之间具有可选空间。

  • nsnanonanosnanosecondnanoseconds
  • us microseconds micromicrosmicrosecond
  • msmillimillismillisecondmilliseconds
  • ssecondseconds
  • mminuteminutes
  • hhourhours
  • ddaydays

例如, 10s 3 days12 hours

预处理器

hoplite支持所谓的预处理器。这些只是从基础配置文件读取的每个值时都应用的函数。预处理器能够根据该预处理器的逻辑来转换值(或返回输入-AKA身份函数)。

例如,预处理器可以选择执行环境变量替换,配置默认值,执行数据库查找或在解决配置时需要的任何其他自定义操作。

您还可以通过将函数与配置ConfigLoader程序类上的withPreprocessor一起添加自定义的预处理器,并在Preprocessor接口的实例中传递。自定义预处理器的典型用例是在数据库中查找某些值,或从Vault或Amazon参数商店等第三方秘密商店中查找一些值。

可以实现的一种方法是具有前缀,然后使用预处理器在字符串中寻找前缀,如果存在前缀,请使用字符串的其余部分作为服务的键。 PrefixProcessor抽象类通过处理节点遍历,同时将特定的处理作为读者的练习来实现这一点。

例如

 database :
  user : root
  password : vault:/my/key/path

注意:您可以通过将withPreprocessingIterationsConfigLoaderBuilder上设置为大于1的属性来反复应用预处理器。这会导致所有预处理器的循环应用。如果您希望一个预处理程序可以解决一个值,那么这可能是有用的,然后需要另一个预处理器解决。

内置预处理器

这些内置的预处理器会自动注册。

预处理器 功能
EnvVarPreprocessor 如果定义,则将表单$ {var}的任何字符串替换为环境变量$ var。这些替换字符串可能会在其他字符串之间发生。

例如foo: hello ${USERNAME}将导致foo被分配值hello Sam假设env var USERNAME已将其设置为SAM 。另外,表达式可以使用常规bash表达式语法foo: hello ${USERNAME:-fallback}

SystemPropertyPreprocessor 如果已定义,则将表单$ {var}的任何字符串替换为system属性$ var。这些替换字符串可能会在其他字符串之间发生。

例如debug: ${DEBUG}将导致debug被分配值true如果应用程序已启动了-Ddebug=true则该值为true。

RandomPreprocessor 将随机字符串插入配置。有关语法,请参见有关随机预处理器的部分。
PropsFilePreprocessor 将表单$ {key}的任何字符串替换为提供的java.util.Properties文件中的密钥值。该文件可以通过类路径上的Path或资源指定。
LookupPreprocessor 将表格{{key}}的任何字符串替换为已解析的配置中的该节点的值。换句话说,这允许从一个地方替换到另一个地方(甚至跨文件)。

可选的预处理器

这些预处理器必须在生效之前将其添加到ConfigBuilder之前,并需要额外的模块才能添加到构建中。

预处理器 功能
AwsSecretsManagerPreprocessor 通过查找AWS Secrets Manager的“键”的值来替换AWSSM:// key的字符串。

该预处理器要求将hoplite -aws模块添加到类路径中。

AzureKeyVaultPreprocessor 通过查找Azure键值Vault的“键”的值来替换AzureKeyVault形式的字符串://键。

该预处理器要求将hoplite -azure模块添加到类路径中。

ParameterStorePreprocessor 通过从AWS Systems Manager参数存储中查找“键”的值来替换$ {SSM:key}的字符串。

该预处理器要求将hoplite -aws模块添加到类路径中。

ConsulConfigPreprocessor 通过查找领事服务器的“键”值来替换表单领事的字符串://键。

该预处理器要求将hoplite -consul模块添加到类路径中。

VaultSecretPreprocessor 通过查找Vault实例的“键”的值来替换表格库的字符串://键。

该预处理器要求将hoplite -vault模块添加到类路径中。

GcpSecretManagerPreprocessor 通过查找Google Cloud Secret Manager实例中的值来替换表单gcpsm://projects/{projectId}/secrets/{secretName}/versions/{version:latest}的字符串。

该预处理器要求将hoplite -gcp模块添加到类路径中。

随机预处理器

随机预处理器用随机值代替占位符字符串。

占位符 生成随机值
$ {random.int} 随机int
$ {random.int(k)} 0和k之间的正随机int
$ {random.int(k,j)} K和J之间的随机int
$ {Random.double} 随机双重
$ {random.boolean 随机布尔
$ {Random.String(k)} 长度为k的随机字母数字字符串
$ {random.uuid} 随机生成的类型4 UUID

例如:

 my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

蒙版值

在调试时,在启动时输出已解决的配置以供参考很常见。在这种情况下,Kotlin的数据类生成的默认toString非常有用。但是,配置通常包括敏感信息,例如密码或密钥,通常您不想在日志中出现。

为了避免在日志输出中出现敏感的字段, hoplite提供了一种内置的类型,称为Masked ,它是围绕字符串的包装器。通过将字段声明为具有此类型,该值仍将从配置文件中加载,但不会包含在生成的toString中。

例如,您可以定义这样的配置类:

data class Database(val host: String, val user: String, val password: Masked)

和相应的JSON配置:

{
  \"host\" : \" localhost \" ,
  \"user\" : \" root \" ,
  \"password\" : \" letmein \"
}

然后,通过toString数据库配置类的输出将是Database(host=localhost, user=root, password=****)

注意:掩蔽效果仅在使用toString时才发生。如果您使用基于反射的工具(例如杰克逊)将配置挂在字符串上,则仍然可以看到基础值。在这些情况下,您需要注册自定义序列化器。对于Jackson项目, hoplite -json模块中有一个hoplite Module对象。将其注册您的Jackson Mapper,例如mapper.registerModule( hoplite Module) ,然后将Masked值输入为JSON,为“ ****”

内联类

一些开发人员包括该作者,喜欢具有强大类型包装简单值。例如, Port对象而不是int。这有助于减轻打字的开发。 Kotlin支持所谓的内联类别满足这一需求。

hoplite直接支持内联类。使用Inline类时,您无需嵌套配置密钥。

例如,给定以下配置类:

 inline class Port ( val value : Int )
inline class Hostname ( val value : String )
data class Database ( val port : Port , val host : Hostname )

然后此配置文件:

 port : 9200
host : localhost

我们可以直接解析:

 val config = ConfigLoader ().loadConfigOrThrow< Database >( \" config.file \" )
println (config.port) // Port(9200)
println (config.host) // Hostname(\"localhost\") 

密封的课程

hoplite将支持密封的类,其中它能够将可用的配置密钥与其中一个实现的参数匹配。例如,让我们创建一个配置层次结构作为密封类的实现。

 sealed class Database {
data class Elasticsearch ( val host : String , val port : Int , val index : String ) : Database()
data class Postgres ( val host : String , val <span cl

下载源码

通过命令行克隆项目:

git clone https://github.com/sksamuel/hoplite.git

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 hoplite https://www.zuozi.net/34169.html

win acme
上一篇: win acme
Craft
下一篇: Craft
常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务