适用于我的应用程序的可扩展CLI

时间:2013-06-13 15:06:47

标签: java spring

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

“”“

添加CLI命令

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

  • 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配置文件和一个属性文件。 / p>

添加。只是。一。命令。

毋庸置疑,缺少许多必需的CLI功能。

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

4 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

如果您遵循这种方法,您可能会考虑使用代码生成(例如使用Eclipse Modeling toolchain),但这会给您的开发过程增加很多复杂性 - 我不确定它是否值得。< / p>

答案 2 :(得分:0)

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

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

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

 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。

答案 3 :(得分:0)

如果我理解正确你的所有命令都是spring bean而且他们必须实现一个特定的(标记)接口?

如果是这样的话。

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

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

    我在这里看到的唯一问题是如果命令不需要在特定包中,如何判断要扫描哪个包。如果你只在内部使用这个cli我会特定一个顶层包需要定义这些命令并挂钩组件扫描这个包所以所有命令都可以通过spring发现而无需任何配置。

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