命令註冊

定義命令註冊是介紹命令及其選項和引數結構的第一步。這與之後發生的事情(例如解析命令列輸入和執行實際目的碼)是鬆散解耦的。本質上,它定義了向用戶展示的命令 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 中的方法、一個 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 作為目標為處理命令執行中的情況提供了很大的靈活性,因為您可以使用提供給 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

使用 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();