命令注册
定义命令注册是介绍命令结构及其选项和参数的第一步。这与后面的步骤(例如解析命令行输入和运行实际目标代码)是松散耦合的。本质上,它是向用户显示的命令API的定义。
命令
在spring-shell
结构中,命令定义为命令数组。这会产生类似于以下示例的结构。
command1 sub1
command2 sub1 subsub1
command2 sub2 subsub1
command2 sub2 subsub2
我们目前不支持将命令映射到显式父级(如果定义了子命令)。例如,command1 sub1 和command1 sub1 subsub1 不能同时注册。 |
交互模式
Spring Shell 旨在支持两种模式:交互式(本质上是一个REPL
,在其中您在多个命令中始终拥有活动的 shell 实例)和非交互式(从命令行逐个执行命令)。
这两种模式之间的区别主要在于每种模式的限制。例如,如果 shell 不再活动,则显示命令之前的堆栈跟踪是不可行的。通常,shell 是否仍然活动决定了可用的信息。
此外,处于活动的REPL
会话中可以提供有关用户在活动会话中执行的操作的更多信息。
选项
选项可以定义为长选项和短选项,前缀分别为--
和-
。以下示例显示了长选项和短选项。
CommandRegistration.builder()
.withOption()
.longNames("myopt")
.and()
.build();
CommandRegistration.builder()
.withOption()
.shortNames('s')
.and()
.build();
目标
目标定义命令的执行目标。它可以是 POJO 中的方法、Consumer
或Function
。
方法
使用现有 POJO 中的Method
是定义目标的一种方法。考虑以下类
public static class CommandPojo {
String command(String arg) {
return arg;
}
}
给定前面列表中显示的现有类,您可以注册其方法
CommandPojo pojo = new CommandPojo();
CommandRegistration.builder()
.command("command")
.withTarget()
.method(pojo, "command")
.and()
.withOption()
.longNames("arg")
.and()
.build();
Function
使用Function
作为目标可以灵活地处理命令执行中发生的情况,因为您可以通过使用传递给Function
的CommandContext
手动处理许多事情。Function
的返回类型随后将作为结果打印到 shell 中。考虑以下示例
CommandRegistration.builder()
.command("command")
.withTarget()
.function(ctx -> {
String arg = ctx.getOptionValue("arg");
return String.format("hi, arg value is '%s'", arg);
})
.and()
.withOption()
.longNames("arg")
.and()
.build();
Consumer
使用Consumer
与使用Function
基本相同,区别在于没有返回类型。如果需要将某些内容打印到 shell 中,则可以从上下文中获取对Terminal
的引用,并通过它打印某些内容。考虑以下示例
CommandRegistration.builder()
.command("command")
.withTarget()
.consumer(ctx -> {
String arg = ctx.getOptionValue("arg");
ctx.getTerminal().writer()
.println(String.format("hi, arg value is '%s'", arg));
})
.and()
.withOption()
.longNames("arg")
.and()
.build();