在 java 中声明自定义可配置应用程序的配置?
Declaring configuration of custom configurable application in java?
因此,对于我的一个爱好项目,我想创建一个应用程序来转换两个服务之间的 HTTP 调用和请求。
应用程序根据用户可以设置的配置执行此操作。这个想法是应用程序监听传入的 API 呼叫转换呼叫然后转发它。
然后应用程序等待响应,然后转换响应并将其发送回调用方。
翻译可以像重命名 body object 中的字段值或将 header 字段替换为 body.
一样简单
我认为翻译应该从映射正确的 URL 开始,所以这是我认为配置应该如下所示的示例:
//request mapping
incoming URL = outgoing URL(
//Rename header value
header.someobject.renameto = "somevalue"
//Replace body object to header
body.someobject.replaceto.header
)
我在想配置应该放在一个.txt文件中,由应用程序读取。
我的问题是,是否有其他类似的系统使用配置文件进行这样的配置?是否有 other/better 种声明配置的方法?
我在不同的上下文中做了一些类似的事情(从输入规范生成代码),所以我将概述我所做的事情以供思考。我使用 Config4*(披露:我开发的)。 如果 我在下面描述的方法对您感兴趣,那么我建议您阅读 Config4* Getting Started Guide 的第 2 章和第 3 章以了解 Config4* 语法和 API。或者,用不同的配置语法表达下面的概念,例如 XML.
Config4*是配置语法,与本次讨论相关的语法子集如下:
# this is a comment
name1 = "simple value";
name2 = ["a", "list of", "values"];
# a list can be laid out in columns to simulate a table of information
name3 = [
# item colour
#------------------
"car", "red",
"jeans", "blue",
"roses", "red",
];
在代码生成器应用程序中,我使用了 table 来提供规则来指定如何生成用于为消息字段赋值的代码。如果没有为特定字段指定规则,则一些内置规则提供默认行为。 table 看起来像下面这样:
field_rules = [
# wildcarded message.field instruction
#----------------------------------------------------------------
"Msg1.username", "@config:username",
"Msg1.password", "@config:password",
"Msg3.price", "@order:price",
"*.account", "@string:foobar",
"*.secondary_account", "@ignore",
"*.heartbeat_interval", "@expr:_heartbeatInterval * 1000",
"*.send_timestamp", "@now",
];
当我的代码生成器想要生成代码来为字段赋值时,代码生成器构造了一个 "<message-name>.<field-name>"
形式的字符串,例如 Msg3.price
。然后逐行(从顶部开始)检查 field_rules
table 以找到第一列与 "<message-name>.<field-name>"
匹配的行。匹配逻辑允许 *
作为可以匹配零个或多个字符的通配符。 (方便的是,Config4* 提供了一个提供此功能的 patternMatch()
实用程序操作。)
如果找到匹配项,则 instruction
列中的值会告诉代码生成器要生成哪种代码。 (如果未找到匹配项,则使用内置规则,如果应用了 none 个规则,则不会为该字段生成代码。)
每条指令都是 "@<keyword>:optional,arguments"
形式的字符串。它被标记化以提供关键字和可选参数。关键字被转换为 enum
,并驱动 switch
语句生成代码。例如:
@config:username
指令指定代码应该是
生成以在运行时分配 username
变量的值
配置文件到字段。
@order:price
指令指定应生成代码
将调用 orderObj->getPrice()
返回的值分配给字段。
@string:foobar
指令指定了字符串文字 foobar
应分配给字段。
@expr:_heartbeatInterval * 1000
指令指定代码应该
生成赋值表达式_heartbeatInterval * 1000
到现场。
@ignore
指令指定不应生成任何代码
为字段赋值。
@now
指令指定应生成代码以分配
该字段的当前时钟时间。
我已经在几个项目中使用了上述技术,并且每次我都发明了针对特定项目需求的指令。如果您决定使用这种技术,那么显然您将需要发明指令来指定运行时转换,而不是生成代码的指令。此外,不要觉得您必须将所有基于翻译的配置硬塞进一个 table。例如,您可以使用一个 table 来提供 source URL -> destination URL 映射,以及另一个 table 到提供翻译消息中字段的说明。
如果这项技术对您和我在我的项目中的效果一样好,那么您的翻译应用程序最终将成为一个“引擎”,其行为完全由配置文件驱动,实际上, 是一种 DSL(领域特定语言)。该 DSL 文件可能非常紧凑(少于 100 行),并且将成为用户可见的应用程序的一部分。因此,值得投入精力使 DSL 尽可能直观和 easy-to-read/modify,因为这样做将使翻译应用程序:(1) 用户友好,以及 (2) 易于记录在用户手册中.
因此,对于我的一个爱好项目,我想创建一个应用程序来转换两个服务之间的 HTTP 调用和请求。
应用程序根据用户可以设置的配置执行此操作。这个想法是应用程序监听传入的 API 呼叫转换呼叫然后转发它。
然后应用程序等待响应,然后转换响应并将其发送回调用方。
翻译可以像重命名 body object 中的字段值或将 header 字段替换为 body.
一样简单我认为翻译应该从映射正确的 URL 开始,所以这是我认为配置应该如下所示的示例:
//request mapping
incoming URL = outgoing URL(
//Rename header value
header.someobject.renameto = "somevalue"
//Replace body object to header
body.someobject.replaceto.header
)
我在想配置应该放在一个.txt文件中,由应用程序读取。
我的问题是,是否有其他类似的系统使用配置文件进行这样的配置?是否有 other/better 种声明配置的方法?
我在不同的上下文中做了一些类似的事情(从输入规范生成代码),所以我将概述我所做的事情以供思考。我使用 Config4*(披露:我开发的)。 如果 我在下面描述的方法对您感兴趣,那么我建议您阅读 Config4* Getting Started Guide 的第 2 章和第 3 章以了解 Config4* 语法和 API。或者,用不同的配置语法表达下面的概念,例如 XML.
Config4*是配置语法,与本次讨论相关的语法子集如下:
# this is a comment
name1 = "simple value";
name2 = ["a", "list of", "values"];
# a list can be laid out in columns to simulate a table of information
name3 = [
# item colour
#------------------
"car", "red",
"jeans", "blue",
"roses", "red",
];
在代码生成器应用程序中,我使用了 table 来提供规则来指定如何生成用于为消息字段赋值的代码。如果没有为特定字段指定规则,则一些内置规则提供默认行为。 table 看起来像下面这样:
field_rules = [
# wildcarded message.field instruction
#----------------------------------------------------------------
"Msg1.username", "@config:username",
"Msg1.password", "@config:password",
"Msg3.price", "@order:price",
"*.account", "@string:foobar",
"*.secondary_account", "@ignore",
"*.heartbeat_interval", "@expr:_heartbeatInterval * 1000",
"*.send_timestamp", "@now",
];
当我的代码生成器想要生成代码来为字段赋值时,代码生成器构造了一个 "<message-name>.<field-name>"
形式的字符串,例如 Msg3.price
。然后逐行(从顶部开始)检查 field_rules
table 以找到第一列与 "<message-name>.<field-name>"
匹配的行。匹配逻辑允许 *
作为可以匹配零个或多个字符的通配符。 (方便的是,Config4* 提供了一个提供此功能的 patternMatch()
实用程序操作。)
如果找到匹配项,则 instruction
列中的值会告诉代码生成器要生成哪种代码。 (如果未找到匹配项,则使用内置规则,如果应用了 none 个规则,则不会为该字段生成代码。)
每条指令都是 "@<keyword>:optional,arguments"
形式的字符串。它被标记化以提供关键字和可选参数。关键字被转换为 enum
,并驱动 switch
语句生成代码。例如:
@config:username
指令指定代码应该是 生成以在运行时分配username
变量的值 配置文件到字段。@order:price
指令指定应生成代码 将调用orderObj->getPrice()
返回的值分配给字段。@string:foobar
指令指定了字符串文字foobar
应分配给字段。@expr:_heartbeatInterval * 1000
指令指定代码应该 生成赋值表达式_heartbeatInterval * 1000
到现场。@ignore
指令指定不应生成任何代码 为字段赋值。@now
指令指定应生成代码以分配 该字段的当前时钟时间。
我已经在几个项目中使用了上述技术,并且每次我都发明了针对特定项目需求的指令。如果您决定使用这种技术,那么显然您将需要发明指令来指定运行时转换,而不是生成代码的指令。此外,不要觉得您必须将所有基于翻译的配置硬塞进一个 table。例如,您可以使用一个 table 来提供 source URL -> destination URL 映射,以及另一个 table 到提供翻译消息中字段的说明。
如果这项技术对您和我在我的项目中的效果一样好,那么您的翻译应用程序最终将成为一个“引擎”,其行为完全由配置文件驱动,实际上, 是一种 DSL(领域特定语言)。该 DSL 文件可能非常紧凑(少于 100 行),并且将成为用户可见的应用程序的一部分。因此,值得投入精力使 DSL 尽可能直观和 easy-to-read/modify,因为这样做将使翻译应用程序:(1) 用户友好,以及 (2) 易于记录在用户手册中.