命令可用性
由于应用程序的内部状态,已注册的命令并不总是合理的。例如,可能存在一个 download
命令,但它仅在用户对远程服务器使用 connect
命令后才能工作。现在,如果用户尝试使用 download
命令,则 shell 应解释该命令存在,但在当时不可用。Spring Shell 允许您执行此操作,甚至允许您提供有关命令不可用的原因的简短说明。
编程方式
使用编程方式注册,您可以使用 availability
方法,该方法接受 Supplier<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();
}
注解
使用基于注解的命令,您可以将 @CommandAvailability
与 AvailabilityProvider
结合使用。
@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.
有关当前不可用命令的信息也用于集成帮助中。请参阅 帮助。
当命令不可用时提供的理由,如果附加在“因为”之后,应该读起来很顺畅。 您不应该以大写字母开头句子或添加句号。 |
如果根据命令方法的名称命名可用性方法不适合您,则可以通过使用 @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 | 名称必须匹配。 |
最后,通常情况下,同一个类中的多个命令共享相同的内部状态,因此应该全部可用或全部不可用。无需将 @ShellMethodAvailability
附加到所有命令方法上,Spring Shell 允许您反过来将 @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");
}
|
Spring Shell 对如何编写命令以及如何组织类没有太多限制。但是,通常将相关的命令放在同一个类中是一个好习惯,可用性指示器可以从中受益。 |