SpringShell 应用启动时, 会自动创建两个ApplicationRunner组件: ScriptShellApplicationRunner 和 InteractiveShellApplicationRunner, 其中ScriptShellApplicationRunner 用来支持启动直接运行脚本方式, InteractiveShellApplicationRunner 用来支持交互式启动方式. 当我们需要新增一种运行方式时, 那么可以通过自定义ApplicationRunner 实现. 深入了解ScriptShellApplicationRunner 和 InteractiveShellApplicationRunner的逻辑, 可阅读笔者的下一篇博客.
1. SpringShell应用默认运行方式
1.1 交互式运行
$ java -jar ./target/spring-shell-0.0.1-SNAPSHOT.jar
# 省略启动信息...
shell:>add 2 3
5
shell:>exit
1.2 脚本运行
$ java -jar ./target/spring-shell-0.0.1-SNAPSHOT.jar
# 省略启动信息...
5
2
4
1.3 笔者期望新增运行方式
$ java -jar ./target/spring-shell-0.0.1-SNAPSHOT.jar
# 省略启动信息...
3
7
2. 自定义ApplicationRunner
- 自定义Input, 实现Input接口, InputProvider.readInput()方法需要返回一个Input类型的值
- 自定义InputProvider, 实现InputProvider接口, Shell.run()方法会调用InputProvider.readInput()获取执行名
- 自定义ApplicationRunner, 实现ApplicationRunner接口, 因为容器初始化完成之后会执行所有ApplicationRunner 的run方法
- 设定ApplicationRunner的优先级, 笔者设定位于默认两个ApplicationRunner 直接, 这个很关键, 直接影响核心代码的编写.
2.1 自定义Input
SpringShell 源码提供了ParsedLineInput, 但是类权限为包级别, 笔者访问不到. 因此复制源码自成一类.
/**
* @Description: 自定义行解析, 复制的底层代码: org.springframework.shell.jline.ParsedLineInput
* @author: zongf
* @date: 2019-01-28 11:18
*/
class MyParsedLineInput implements Input {
private final ParsedLine parsedLine;
MyParsedLineInput(ParsedLine parsedLine) {
this.parsedLine = parsedLine;
}