0

我维护一个内部用于测试基础设施的应用程序。通常,它只需要在整个测试期间在一台设备上运行,但有时我们需要从这个应用程序中获取信息,或者在运行时对其进行操作。出于这个目的,它有一个 CLI,但是,唉,这是我为自己写的关于如何添加新的 CLI 命令的说明:

"""

添加 CLI 命令

  • 在 cli/client/commands/{category}/CLINewCommand.java 和 cli/server/commands/{category}/NewCommand.java 中为新命令创建一个类

  • CLI类必须扩展 CLICOnfigCmd 并实现 CLICommand。*

  • 将命令添加到 cli/client/commands/SimServerCmd.java 中的枚举并使用 cli/client/commands/CLICommandFactory.java 中的枚举值

  • 将命令类添加到 cli/server/RepositoryInfo.java 并添加一个公共方法来调用它的服务器端命令。该命令也必须添加到接口 RepositoryInfoMBean 中。

  • *初始化 config/applicationContext.xml 和 config/cliApplicationContext.xml 中的新对象。在 config/simulator_cli_conf.properties 中添加要打印的字符串*

"""

因此,如果您设法按照我古怪的自我发现说明进行操作,为了添加 CLI 命令,您需要为命令创建 2 个类,编辑 4 个不同的类,然后编辑两个 Spring 配置文件和一个属性文件。

用于添加。只是。一。命令。

不用说,缺少许多必需的 CLI 功能。

您对更好的设计有什么建议吗?更好的是易于扩展。

4

4 回答 4

0

我使用 Commons CLI。它很好地阻止了我思考 cli。

http://commons.apache.org/proper/commons-cli/

于 2013-06-13T15:26:32.133 回答
0

您可能想尝试ServiceLoader系统。让您的CLICommand界面至少包含以下内容:

void execute(MyApplication app);
String cliName();
void setArgument(String argument);

META-INF/services/com.example.CLICommand为每个新命令创建一个 jar,并将新命令类的完全限定名称放入文件中。在您的应用程序类中,使用以下命令查询类路径:

 private static ServiceLoader<CLICommand> cliLoader
     = ServiceLoader.load(CLICommand.class);

并遍历命令cliLoader以获取命令行选项名称。

例如,

public class VerboseCommand {
    private boolean verbose = false;
    public String cliName() {
        return "verbose";
    }

    public void setArgument(String argument) {
        if (argument != null && !argument.isEmpty()) {
            this.verbose = Boolean.valueOf(argument);
        } else {
            this.verbose = true;
        }
    }
    public void execute(MyApplication app) {
        app.setVerbose(verbose);
    }
}

现在,如果有人执行命令verbose,应用程序会看到该行,将其分解为参数,使用查找verbose并找到VerboseCommand实例,并向其发送 null 或空字符串。然后该命令将应用程序的verbose属性设置为 true。

然而,对于喜欢这种东西的人来说,也可以使用 JMX。

于 2013-06-13T15:47:54.777 回答
0

如果您采用这种方法,您可能会考虑使用代码生成(例如使用Eclipse 建模工具链),但是这会给您的开发过程增加很多复杂性——我不确定它是否值得。

于 2013-06-13T15:33:13.773 回答
0

如果我理解正确,您的所有命令都将是 spring bean,并且它们必须实现特定的(标记)接口?

如果是这样的话,那该怎么办。

  • 命令接口定义了一个需要实现的方法execute(properties)。

  • 命令服务提供 cli 工具来选择命令并执行它。在这里,您可以将所有发现的命令自动连接为一个列表,并且该设施使用它。

    我在这里看到的唯一问题是如果命令不需要位于特定包中,如何判断要扫描哪个包。如果您仅在内部使用此 cli,我将指定一个顶级包,这些命令需要在其中定义并挂钩此包上的组件扫描,以便 spring 无需任何配置即可发现所有命令。

您需要实现的只是一个使用@Component 注释的命令类。

于 2013-06-13T15:53:47.923 回答