此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Shell 3.3.3spring-doc.cadn.net.cn

命令可用性

由于应用程序的内部状态,注册的命令并不总是有意义。 例如,可能有一个download命令,但只有在用户使用了connect在远程 服务器。现在,如果用户尝试使用download命令,shell 应该解释 命令存在,但当时不可用。 Spring Shell 允许你这样做,甚至允许你提供 命令不可用。spring-doc.cadn.net.cn

编程

通过编程注册,您可以使用availability方法,该方法采用Supplier<Availability>.spring-doc.cadn.net.cn

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.spring-doc.cadn.net.cn

@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");
	}
}

旧版注释

命令有三种可能的方式来指示可用性。 它们都使用一个 no-arg 方法,该方法返回一个Availability. 请考虑以下示例:spring-doc.cadn.net.cn

@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");
	}
}

connectmethod 连接到服务器(省略细节),从而更改状态 的命令中connectedboolean 值。 这download命令标记为不可用,直到用户已连接,这要归功于 与名称完全相同的方法downloadcommand 方法替换为Availabilitysuffix 在其名称中。 该方法返回Availability,使用两种工厂方法之一构造。 如果该命令不可用,则必须提供解释。 现在,如果用户尝试在未连接的情况下调用命令,则情况如下:spring-doc.cadn.net.cn

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.

集成帮助中还使用了有关当前不可用命令的信息。请参阅帮助spring-doc.cadn.net.cn

如果将命令不可用时提供的原因附加到 “Because” 之后,则应该读起来很不错。spring-doc.cadn.net.cn

您不应以大写字母开头或添加最后一个句点spring-doc.cadn.net.cn

如果在命令方法名称后命名 availability 方法不适合您,您可以 可以使用@ShellMethodAvailability注解:spring-doc.cadn.net.cn

@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 名称必须匹配

最后,通常情况下,同一类中的多个命令共享相同的内部状态,因此, 应全部作为一个组可用或不可用。不必粘贴@ShellMethodAvailability在所有命令方法上,Spring Shell 都允许您翻转事物并将@ShellMethodAvailabilty注解,指定它控制的命令的名称:spring-doc.cadn.net.cn

@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()attribute 为 .这个特别的 通配符匹配所有命令名称。这样就可以轻松打开或关闭单个类的所有命令 使用单一可用性方法:*spring-doc.cadn.net.cn

@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 对如何编写命令和如何组织类没有施加很多约束。 但是,将相关命令放在同一个类中通常是一种很好的做法,并且可用性指示符 可以从中受益。