Java 适用于我的应用程序的可扩展CLI
我维护一个内部用于测试基础设施的应用程序。通常,在整个测试过程中,它只需要在一个设备上运行,但偶尔我们需要从这个应用程序中获取信息,或者在运行时对其进行操作。 出于上述目的,它有一个CLI,但遗憾的是,以下是我为自己编写的关于如何添加新CLI命令的说明: “”“ 添加CLI命令Java 适用于我的应用程序的可扩展CLI,java,spring,Java,Spring,我维护一个内部用于测试基础设施的应用程序。通常,在整个测试过程中,它只需要在一个设备上运行,但偶尔我们需要从这个应用程序中获取信息,或者在运行时对其进行操作。 出于上述目的,它有一个CLI,但遗憾的是,以下是我为自己编写的关于如何添加新CLI命令的说明: “”“ 添加CLI命令 在cli/client/commands/{category}/CLINewCommand.java和cli/server/commands/{category}/NewCommand.java中为新命令创建类 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\u cli\u conf.properties中打印*
你对更好的设计有什么建议吗?更好的是易于扩展 我使用Commons CLI。它很好地阻止了我考虑cli
如果你遵循这个方法,你可能会考虑使用代码生成(例如,用它),但是这会给你的开发过程增加很多的复杂性——我不确定它是否值得。 你可能想试试这个系统。让您的
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);
现在,如果有人执行命令verbose
,应用程序将看到该行,将其分解为参数,使用查找verbose
,找到verbose命令
实例,并向其发送null或空字符串。然后,该命令将应用程序的verbose
属性设置为true
但是,对于喜欢这类东西的人,也可以使用JMX。如果我理解正确,您的所有命令都将是SpringBean,它们必须实现特定的(标记)接口 如果是这样的话,这个怎么样
- 命令接口定义了一个需要实现的方法execute(属性)
- 命令服务提供了cli工具,用于选择并执行命令。在这里,您可以将所有发现的命令自动关联为一个列表,然后设备使用它 我在这里看到的唯一问题是,如果命令不需要在特定的包中,如何告诉要扫描哪个包。如果您仅在内部使用此cli,我将指定一个顶级包,这些命令需要在该包中定义并钩住组件扫描,以便spring可以在不进行任何配置的情况下发现所有命令
您只需要实现一个用@Component注释的命令类 添加一个命令意味着——通过控制台添加一个新的输入参数和值,这是一个正确的假设吗?更多的调查向我揭示,实际上正在使用JMX。我会读更多的关于。
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);
}
}