通过Spring Shell 开发 Java 命令行应用

2019-09-23 09:00:59刘景俊

在代码清单 10 中,我们为 PrefixedResult 添加了具体的处理器实现。该实现也非常简单,只是把结果按照某个格式进行输出。

清单 10. PrefixedResult 对应的处理器实现

@Component
public class PrefixedResultHandler implements ResultHandler<PrefixedResult> {
 
 @Override
 public void handleResult(PrefixedResult result) {
 System.out.printf("%s --> %s%n", result.getPrefix(), result.getResult());
 }
}

在代码清单 11 中,命令方法 resultHandler 返回的是一个 PrefixedResult 对象,因此会被代码清单 10 中的处理器来进行处理,输出相应的结果。

清单 11. 使用 PrefixedResult 的命令

@ShellComponent
public class CustomResultHandlerApp {
 @ShellMethod("Result handler")
 public PrefixedResult resultHandler() {
 return new PrefixedResult("PRE", "Hello!");
 }
}

代码清单 12 给出了具体的命令运行结果。

清单 12. 命令的处理结果

myshell=>result-handler
PRE --> Hello!

自定义提示符

在启动命令行应用时,会发现该应用使用的是默认提示符"shell:>"。该提示符是可以定制的,只需要提供接口 org.springframework.shell.jline.PromptProvider 的实现即可。接口 PromptProvider 中只有一个方法,用来返回类型为 org.jline.utils.AttributedString 的提示符。在代码清单 13 中,我们定义了一个 PromptProvider 接口的实现类,并使用"myshell=>"作为提示符,而且颜色为蓝色。

清单 13. 自定义提示符

@Bean
public PromptProvider promptProvider() {
 return () -> new AttributedString("myshell=>",
  AttributedStyle.DEFAULT.foreground(AttributedStyle.BLUE));
}

动态命令可用性

前面所创建的命令都是一直可用的。只要应用启动起来,就可以使用这些命令。不过有些命令的可用性可能取决于应用的内部状态,只有内部状态满足时,才可以使用这些命令。对于这些命令,Spring Shell 提供了类 org.springframework.shell.Availability 来表示命令的可用性。通过类 Availability 的静态方法 available()和 unavailable()来分别创建表示命令可用和不可用的 Availability 对象。

在代码清单 14 中,我们创建了两个命令方法 runOnce()和 runAgain()。变量 run 作为内部状态。在运行 runOnce()之后,变量 run 的值变为 true。命令 runAgain 的可用性由方法 runAgainAvailability()来确定。该方法根据变量 run 的值来决定 runAgain 是否可用。按照命名惯例,检查命令可用性的方法的名称是在命令方法名称之后加上 Availability 后缀。如果需要使用不同的方法名称,或是由一个检查方法控制多个方法,可以在检查方法上添加注解@ShellMethodAvailability 来声明其控制的方法名称。

清单 14. 动态命令可用性