【问题标题】:Declaring configuration of custom configurable application in java?在java中声明自定义可配置应用程序的配置?
【发布时间】:2021-02-22 05:52:25
【问题描述】:

因此,对于我的一个爱好项目,我想创建一个应用程序来转换两个服务之间的 HTTP 调用和请求。

应用程序根据用户可以设置的配置执行此操作。这个想法是应用程序侦听传入的 API 调用,然后转换调用,然后转发它。

然后应用程序等待响应,然后翻译响应并将其发送回调用方。

翻译可以像重命名正文对象中的字段值或将标题字段替换为正文一样简单。

我认为翻译应该从映射正确的 URL 开始,所以这里是我认为配置应该如下所示的示例:

    //request mapping
    incoming URL = outgoing URL(
    
        //Rename header value
        header.someobject.renameto = "somevalue"
        
        //Replace body object to header
        body.someobject.replaceto.header
    )

我在想配置应该放在一个 .txt 文件中并由应用程序读取。

我的问题是,是否还有其他类似的系统使用配置文件进行这样的配置?还有其他/更好的方法来声明配置吗?

【问题讨论】:

    标签: java text configuration configuration-management design-decisions


    【解决方案1】:

    我在不同的上下文中做了一些类似的事情(从输入规范生成代码),所以我将概述我所做的事情以提供一些思考。我使用了 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",
    ];
    

    在代码生成器应用程序中,我使用表格提供规则来指定如何生成代码以将值分配给消息字段。如果没有为特定字段指定规则,则某些内置规则会提供默认行为。该表如下所示:

    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 表以找到第一列与"<message-name>.<field-name>" 匹配的行。匹配逻辑允许 * 作为可以匹配零个或多个字符的通配符。 (方便地,Config4* 提供了一个提供此功能的patternMatch() 实用程序操作。)

    如果找到匹配项,则 instruction 列中的值会告诉代码生成器要生成哪种代码。 (如果未找到匹配项,则使用内置规则,如果未应用这些规则,则不会为该字段生成任何代码。)

    每条指令都是"@<keyword>:optional,arguments" 形式的字符串。这被标记为提供关键字和可选参数。关键字被转换为enum,并驱动switch 语句生成代码。例如:

    • @config:username 指令指定代码应为 生成以在运行时分配 username 变量的值 配置文件到现场。
    • @order:price 指令指定应生成代码 将调用 orderObj->getPrice() 返回的值分配给该字段。
    • @string:foobar 指令指定字符串文字 foobar 应分配给该字段。
    • @expr:_heartbeatInterval * 1000 指令指定代码应该 生成赋值表达式_heartbeatInterval * 1000 到现场。
    • @ignore 指令指定不应生成任何代码 为字段赋值。
    • @now 指令指定应生成代码以分配 现场的当前时钟时间。

    我在几个项目中使用了上述技术,并且每次我都针对特定项目的需求发明了特定的说明。如果您决定使用这种技术,那么显然您将需要发明指令来指定运行时转换,而不是生成代码的指令。此外,不要觉得您必须将所有基于翻译的配置硬塞到一个表中。例如,您可以使用一个表来提供 源 URL -> 目标 URL 映射,并使用另一个表来提供翻译消息中字段的说明。

    如果这项技术对您和我的项目一样有效,那么您的翻译应用程序最终将成为一个“引擎”,其行为完全由配置文件驱动,实际上是DSL(领域特定语言)。该 DSL 文件可能非常紧凑(少于 100 行),并且将成为用户可见的应用程序的一部分。因此,值得投入精力使 DSL 尽可能直观且易于阅读/修改,因为这样做将使翻译应用程序:(1)用户友好,以及(2)易于以用户手册。

    【讨论】:

    • 我会尝试使用这个解决方案,如果我能完成这个项目,我会把它开源!我感谢编写良好的解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 2017-01-21
    • 2019-03-23
    • 1970-01-01
    相关资源
    最近更新 更多