命令可用性
注册的命令并非总是有效,这取决于应用程序的内部状态。例如,可能有一个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
命令方法同名且带有 Availability
后缀的方法,download
命令被标记为不可用,直到用户连接成功。该方法返回一个 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 | 名称必须匹配 |
最后,同类中的多个命令经常共享相同的内部状态,因此应该作为一个组同时可用或不可用。与其在所有命令方法上都添加 @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 对如何编写命令和组织类没有施加太多限制。然而,通常将相关命令放在同一个类中是一个很好的实践,可用性指示器也能从中受益。 |