Spring Shell 是用来开发类似于Linux Shell, Python Shell 等交互式终端应用的. 和传统的java web 应用不同, 用户和应用的交互方式不再是通过绚丽多彩的页面, 而是通过低调内涵的命令行窗口. Spring Shell 给开发者提供了一个开发Shell应用的架构, 自带了Tab补全, 颜色高亮显示等特性, 使开发者只用关注于自己的命令逻辑即可.
Spring Shell 应用依赖于SpringBoot 环境, 所以需要新建一个SpringBoot 应用.
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell-starter</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
@ShellComponent
public class CalculatorCommands {
@ShellMethod("计算两个整数的加法")
public int add(int a, int b){
return a + b;
}
@ShellMethod("计算两个整数的减法")
public int minus(int a, int b) {
return a - b;
}
@ShellMethod("计算两个整数的乘法")
public int multiply(int a, int b) {
return a * b;
}
@ShellMethod("计算两个整数的除法")
public int div(int a, int b) {
return a/b;
}
}
Spring Shell 虽然也是Spring boot 应用, 也可以通过直接run Application类运行, 但是这种方式交互效果并不太好, 也可能是由于笔者的开发工具有问题(笔者开发环境为linux+idea). 因此, 笔者推荐先打包, 再运行. 打包时需要跳过测试, 否则在有测试用例的情况下, 打包可能不能运行.
mvn clean && mvn package -DskipTests
启动shell项目和启动普通的spring boot 项目没什么差别, 直接使用java 命令启动即可
$ java -jar spring-shell-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.2.RELEASE)
2019-01-25 16:05:59.260 INFO 14751 --- [ main] o.z.l.s.shell.SpringShellApplication : Starting SpringShellApplication v0.0.1-SNAPSHOT on zongf-E570 with PID 14751 (/data/idea/learn-spring/spring-shell/target/spring-shell-0.0.1-SNAPSHOT.jar started by zongf in /data/idea/learn-spring/spring-shell/target)
2019-01-25 16:05:59.265 INFO 14751 --- [ main] o.z.l.s.shell.SpringShellApplication : No active profile set, falling back to default profiles: default
2019-01-25 16:06:00.561 INFO 14751 --- [ main] o.z.l.s.shell.SpringShellApplication : Started SpringShellApplication in 1.79 seconds (JVM running for 2.263)
shell:>
Spring Shell 和 linux shell 类似, 也支持Tab 自动补全命令和clear 快速清屏等操作.
help 可以查看应用所支持的内置命令和用户自定义命令
shell:>help
AVAILABLE COMMANDS
# 所有内置命令
Built-In Commands
clear: Clear the shell screen.
exit, quit: Exit the shell.
help: Display help about available commands.
script: Read and execute commands from a file.
stacktrace: Display the full stacktrace of the last error.
# 自定义命令
Calculator Commands
add: 计算两个整数的加法
div: 计算两个整数的除法
minus: 计算两个整数的减法
multiply: 计算两个整数的乘法
help 也可以查看命令详情, 命令描述, 所需要参数等
shell:>help add
NAME
add - 计算两个整数的加法
SYNOPSYS
add [--a] int [--b] int
OPTIONS
--a int
[Mandatory]
--b int
[Mandatory]
调用方式和执行shell命令相似, 直接输入命令紧跟参数即可, 也可使用Tab键自动补全命令.
shell:>add 1 2
3
shell:>div 2 0
/ by zero
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
stacktrace 会打印上次运行出现异常的堆栈信息.
shell:>stacktrace
java.lang.ArithmeticException: / by zero
at org.zongf.learn.spring.shell.cmd.CalculatorCommands.div(CalculatorCommands.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:246)
at org.springframework.shell.Shell.evaluate(Shell.java:169)
at org.springframework.shell.Shell.run(Shell.java:134)
at org.springframework.shell.jline.InteractiveShellApplicationRunner.run(InteractiveShellApplicationRunner.java:84)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:794)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:324)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at org.zongf.learn.spring.shell.SpringShellApplication.main(SpringShellApplication.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
和linux shell 类似, 可以通过使用clear 或者 Ctrl + L 快速清屏
shell:>clear
shell:>exit
由于每次修改应用都需要重新打包, 然后运行测试, 步骤比较繁琐. 因此笔者就写了一段脚本, 用于快速的打包和运行程序.
#!/bin/bash
#Desc spring-shell 项目
#Auth zongf
#Date 2019-01-25
# 打包
function package(){
# 切换目录
script_path=`cd $(dirname $0); pwd`
cd `dirname $script_path`
# 清理
mvn -s $settings clean
# 打包
mvn -s $settings -DskipTests package
}
# 运行程序
function run(){
# 切换目录
script_path=`cd $(dirname $0); pwd`
cd `dirname $script_path`/target
# 运行程序
java -jar spring-shell-0.0.1-SNAPSHOT.jar
}
######################################## main ########################################
# 配置位置
settings="/opt/app/maven/apache-maven-2.2.1/conf/settings.xml"
if [ "$1" == "package" ]; then
package
else
run
fi
./spring-shell.sh package
./spring-shell.sh
SpringShell 项目依赖于JLine 模块儿, 因此从JLine中继承了一些优良的交互方式, 提供了一些Shell终端交互的快捷键: