命令可用性

由於應用程式的內部狀態,已註冊的命令並非總是有意義。例如,可能有一個download命令,但它只有在使用者在遠端伺服器上使用connect後才起作用。現在,如果使用者嘗試使用download命令,shell應該解釋該命令存在但當前不可用。Spring Shell允許您這樣做,甚至允許您提供命令不可用的原因的簡短解釋。

程式設計式

透過程式設計式註冊,您可以使用採用Supplier<Availability>availability方法。

private boolean connected;

@Bean
public CommandRegistration connect(
		CommandRegistration.BuilderSupplier builder) {
	return builder.get()
		.command("connect")
		.withOption()
			.longNames("connected")
			.required()
			.type(boolean.class)
			.and()
		.withTarget()
			.consumer(ctx -> {
				boolean connected = ctx.getOptionValue("connected");
				this.connected = connected;
			})
			.and()
		.build();
}

@Bean
public CommandRegistration download(
		CommandRegistration.BuilderSupplier builder) {
	return builder.get()
		.command("download")
		.availability(() -> {
			return connected
				? Availability.available()
				: Availability.unavailable("you are not connected");
		})
		.withTarget()
			.consumer(ctx -> {
				// do something
			})
			.and()
		.build();
}

註解

對於基於註解的命令,您可以將@CommandAvailabilityAvailabilityProvider一起使用。

@Command
class MyCommands {

	private boolean connected;

	@Command(command = "connect")
	public void connect(String user, String password) {
		connected = true;
	}


	@Command(command = "download")
	@CommandAvailability(provider = "downloadAvailability")
	public void download(
	) {
		// do something
	}

	@Bean
	public AvailabilityProvider downloadAvailability() {
		return () -> connected
			? Availability.available()
			: Availability.unavailable("you are not connected");
	}
}

傳統註解

命令指示可用性有三種可能的方式。它們都使用一個無引數方法,該方法返回Availability例項。考慮以下示例:

@ShellComponent
public class MyCommands {

	private boolean connected;

	@ShellMethod("Connect to the server.")
	public void connect(String user, String password) {
		// do something
		connected = true;
	}

	@ShellMethod("Download the nuclear codes.")
	public void download() {
		// do something
	}

	public Availability downloadAvailability() {
		return connected
			? Availability.available()
			: Availability.unavailable("you are not connected");
	}
}

connect方法用於連線到伺服器(詳細資訊省略),在完成時透過connected布林值改變命令的狀態。download命令被標記為不可用,直到使用者連線,這得益於一個方法,該方法與download命令方法的名稱完全相同,並在其名稱中帶有Availability字尾。該方法返回一個Availability例項,該例項透過兩個工廠方法之一構造。如果命令不可用,則必須提供解釋。現在,如果使用者在未連線時嘗試呼叫該命令,則會發生以下情況:

shell:>download
Command 'download' exists but is not currently available because you are not connected.
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.

有關當前不可用命令的資訊也用於整合幫助中。請參閱 幫助

當命令不可用時提供的理由,如果附加在“Because”之後,應該讀起來很順暢。

您不應該以大寫字母開頭句子或新增句號。

如果將可用性方法命名為命令方法名稱不適合您,您可以透過使用@ShellMethodAvailability註解提供一個顯式名稱

@ShellMethod("Download the nuclear codes.")
@ShellMethodAvailability("availabilityCheck") (1)
public void download() {
}

public Availability availabilityCheck() { (1)
	return connected
		? Availability.available()
		: Availability.unavailable("you are not connected");
}
1 名稱必須匹配

最後,通常情況下,同一類中的幾個命令共享相同的內部狀態,因此應該作為一個組全部可用或全部不可用。Spring Shell不是在所有命令方法上都放置@ShellMethodAvailability,而是讓您反過來將@ShellMethodAvailabilty註解放在可用性方法上,並指定它控制的命令的名稱

@ShellMethod("Download the nuclear codes.")
public void download() {
}

@ShellMethod("Disconnect from the server.")
public void disconnect() {
}

@ShellMethodAvailability({"download", "disconnect"})
public Availability availabilityCheck() {
	return connected
		? Availability.available()
		: Availability.unavailable("you are not connected");
}

@ShellMethodAvailability.value()屬性的預設值為*。這個特殊的萬用字元匹配所有命令名稱。這使得使用單個可用性方法輕鬆地開啟或關閉單個類的所有命令。

@ShellComponent
public class Toggles {

	@ShellMethodAvailability
	public Availability availabilityOnWeekdays() {
		return Calendar.getInstance().get(DAY_OF_WEEK) == SUNDAY
			? Availability.available()
			: Availability.unavailable("today is not Sunday");
	}

	@ShellMethod
	public void foo() {}

	@ShellMethod
	public void bar() {}
}
Spring Shell對如何編寫命令以及如何組織類沒有太多限制。但是,將相關命令放在同一類中通常是一種好的做法,並且可用性指示器可以從中受益。
© . This site is unofficial and not affiliated with VMware.