命令可用性

由于应用程序的内部状态,已注册的命令并非总是有意义。例如,可能有一个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.