命令注册

定义命令注册是引入命令及其选项和参数结构的第一步。这与稍后发生的事情(例如解析命令行输入和运行实际目标代码)松散解耦。本质上,它是向用户展示的命令 API 的定义。

命令

spring-shell 结构中,命令被定义为命令数组。这会产生一个类似于以下示例的结构

command1 sub1
command2 sub1 subsub1
command2 sub2 subsub1
command2 sub2 subsub2
我们目前不支持将命令映射到显式父级(如果定义了子命令)。例如,不能同时注册 command1 sub1command1 sub1 subsub1

交互模式

Spring Shell 已设计为在两种模式下工作:交互式(本质上是一个 REPL,您在整个系列命令中都有一个活动的 shell 实例)和非交互式(命令从命令行逐个执行)。

这些模式之间的区别主要在于每种模式下的限制。例如,如果 shell 不再活动,则无法显示命令的先前堆栈跟踪。通常,shell 是否仍处于活动状态决定了可用信息。

此外,在活动的 REPL 会话中可以提供更多关于用户在活动会话中所做的事情的信息。

选项

选项可以定义为长选项和短选项,前缀分别为 ---。以下示例展示了长选项和短选项

CommandRegistration.builder()
	.withOption()
		.longNames("myopt")
		.and()
	.build();
CommandRegistration.builder()
	.withOption()
		.shortNames('s')
		.and()
	.build();

目标

目标定义了命令的执行目标。它可以是 POJO 中的方法、ConsumerFunction

方法

使用现有 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 作为目标可以为命令执行中发生的事情提供很大的灵活性,因为您可以通过使用提供给 FunctionCommandContext 来手动处理许多事情。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 基本与使用 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();
© . This site is unofficial and not affiliated with VMware.