SpringBoot Shell使用简介

背景

SpringBoot Shell基于JLine库实现了REPL(READ EVAL PRINT LOOP) 模式的命令行工具,给我们提供了方便的使用命令行的工具。

使用入门

通过https://start.spring.io/创建SpringBoot项目,并添加依赖。

<dependency>
    <groupId>org.springframework.shell</groupId>
    <artifactId>spring-shell-starter</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>

随后启动系统可以会自动进入到shell模式.

shell:>

如果想在系统启动时,禁用默认的shell模式,那么在配置文件中增加如下配置[2]。

spring.shell.interactive.enabled=false

当false禁用shell模式,为true时启用shell模式。

创建命令

通过@ShellComponent注解标注类,@ShellMethod标注方法,表示要创建的命令,方法参数为命令参数。

@ShellComponent
public class MyCommands {

    @ShellMethod("Add two integers together.")
    public int add(int a,int b){
        return a + b;
    }
}

在控制台输入命令,会产生相应的输出

shell:>add 1 2
3

自定义命令名称

默认情况下不需要为命令指定key,方法名将被用来作为命令名称。驼峰式命名奖杯转换为横线连接的名称。例如sayHello()转换为say-hello。输入命令时需要使用say-hello。如果需要显示设定命令名可以使用注解的key属性。

@ShellMethod(value = "Add numbers.", key = "sum")public int add(int a, int b) {return a + b;
       }
shell:>sum 1 2
3

key可以接收多个参数,这个不同的参数将作为命令的别名来使用。

@ShellComponent
public class MyCommands {

    @ShellMethod(value = "Add two integers together.",key = {"sum","s"})
    public int add(int a,int b){
        return a + b;
    }
}
shell:>s 1 2
3

按名称或通过位置参数调用调用命令

echo命令的调用有两种方式
1.使用参数关键字调用,通过 --参数名 值 形式调用
2.不使用参数关键字,而直接穿入参数,并按参数出现的顺序来调用命令。

@ShellMethod("Display stuff.")public String echo(int a, int b, int c) {return String.format("You said a=%d, b=%d, c=%d", a, b, c);}
shell:>echo 1 2 3               
You said a=1, b=2, c=3

shell:>echo --a 1 --b 2 --c 3   
You said a=1, b=2, c=3

shell:>echo --b 2 --c 3 --a 1   
You said a=1, b=2, c=3

shell:>echo --a 1 2 3           
You said a=1, b=2, c=3

shell:>echo 1 --c 3 2           
You said a=1, b=2, c=3

1.直接写参数顺序来调用,a为1 ,b为2,c为3
2.通过参数关键字来调用,–a指定为1 --b为2,–c为3
3.通过参数关键字来调用,并改变顺序。
4,5通过两种方式混合来调用,顺序可通过输出清楚看明白。

自定义命名参数

上面的例子,我们通过参数 --参数名 来设置命令对应参数的值。此外也可以通过@ShellOption注解自定义参数名及前缀。而未通过ShellOption定义的参数,将通过注解参数prefix修改变默认前缀。

@ShellMethod(value = "Display stuff.", prefix="-")public String echo(int a, int b, @ShellOption("--third") int c) {return String.format("You said a=%d, b=%d, c=%d", a, b, c);      
}
shell:>echo -a 1 -b 2 --third 3
You said a=1, b=2, c=3

@ShellOption({"–third","-t"})也可以接收多个参数

shell:>echo -a 1 -b 2 -t 3
You said a=1, b=2, c=3

可选参数与默认值

可以通过@ShellOption的参数defaultValue指定默认值。

@ShellMethod("Say hello.")
public String greet(@ShellOption(defaultValue="World") String who) {
       return "Hello " + who;
}
shell:>greet
Hello World

多元参数

有时一个参数可能会接收多个值,这时就需要用到@ShellOption注解的arity参数。

@ShellMethod("Add numbers.")
public float add(@ShellOption(arity = 3) float[] numbers) {
    return numbers[0] + numbers[1] + numbers[2];
}

shell:>add 1 2 3.3
6.3
shell:>add --numbers 1 2 3.3
6.3

Boolean参数的处理

@ShellMethod("Terminate the system")
public String shutdown(boolean force) {
    return "You said " + force;
}

shell:>shutdown
You said false
shell:>shutdown --force
You said true

boolean参数默认值为false,当指定参数选项 --force时输出为true。

此外可以通过@ShellOption(arity = 1 ,defaultValue = “true”)boolean参数默认值。

@ShellMethod("Terminate the system")
public String shutdown(@ShellOption(arity = 1 ,defaultValue = "true") boolean force) {
    return "You said " + force;
}

shell:>shutdown false
You said false
shell:>shutdown
You said true

引号处理

Spring shell默认通过空格分割命令,如果命令中包含空格,那么需要通过单引号或双引来指定使用的参数。

@ShellMethod("Prints what has been entered")
public String echo(String what) {
    return "You said " + what;
}

shell:>echo "hello word"
You said hello word

如果参数中有单引号,那么可以通过双引号包围参数,两者混合使用。

shell:>echo "hello i'm here"
You said hello i'm here

如果只用一种类型引号,且参数中还需要用到这种引号作为参数,那么需要使用转义符号。

shell:>echo 'i\'m here'
You said i'm here

此外还可以对空格转义。

shell:>echo this\ is
You said this is

验证命令参数

Spring shell集成了Bean Validation API,支持参数校验。校验将在命令执行前进行。

@ShellMethod("Change password.")
public String changePassword(@Size(min = 8,max = 40)String password) {
    return "Password successfully set to " + password;
}

shell:>change-password as
The following constraints were not met:
	--password string : 个数必须在840之间 (You passed 'as')

检查命令的可用性

某些命令必的执行需要前置命令执行完毕才可以执行。例如 下载文件需要先执行连接(connect),接着再执行(download)。Spring shell提供了3种方式执行可用性验证。利用Availability对象实例来实现检测。

下面的例子中,connect方法被调用后,变量connected被设置为true,download方法才可以正常调用。由于增加了方法downloadAvailability,即为方法名download增加了后缀Availability,在download被调用时会检查downloadAvailability返回的Availability实例。若不可用会返回提示信息。

@ShellComponent
public class MyCommands {

    private boolean connected;

    @ShellMethod("connection server")
    public void connect(String user,String password) {
        connected = true;
    }

    @ShellMethod("download nuclear code")
    public void download() {
    }

    Availability downloadAvailability() {
        return connected ? Availability.available() :
                Availability.unavailable("You are not connected");
    }
 }


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.
shell:>connect
Parameter '--user string' should be specified
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
shell:>connect m n
shell:>download
shell:>

若不便于为方法增加Availability后缀来添加检查方法。还可以使@ShellMethodAvailability注解显式指定检查方法。

@ShellComponent
public class MyCommands {

    private boolean connected;

    @ShellMethod("connection server")
    public void connect(String user,String password) {
        connected = true;
    }

    @ShellMethod("download nuclear code")
    @ShellMethodAvailability("vailabilityCheck")
    public void download() {
    }

    Availability vailabilityCheck() {
        return connected ? Availability.available() :
                Availability.unavailable("You are not connected");
    }
}

实际使用中,存在多个后继命令,在前置命令被执行后才可以使用。那么通过@ShellMethodAvailability指定多个命令即可。

@ShellComponent
public class MyCommands {

    private boolean connected;

    @ShellMethod("connection server")
    public void connect(String user,String password) {
        connected = true;
    }

    @ShellMethod("download nuclear code")
    public void download() {
    }

    @ShellMethod("disconnect")
    public void disconnected() {
    }

    @ShellMethodAvailability({"download","disconnected"})
    Availability vailabilityCheck() {
        return connected ? Availability.available() :
                Availability.unavailable("You are not connected");
    }
 }

组织命令

当输入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.

My Commands
        add: Add numbers.
        change-password: Change password.
        connect: connection server
        disconnected: disconnect
        download: download nuclear code
        echo: Prints what has been entered
        greet: Say hello.
        s, sum: Add two integers together.
        shutdown: Terminate the system


shell:>

命令默认情况下是按照所在类的类名来组织的。此外可以按优先级顺序按如下方式下自定义。最后可输入help命令来验证分组结果。
1.在@ShellMethod注解中通过group属性来指定。
2.在class上使用@ShellCommandGroup注解来定义。
3.在package-info.java文件中使用@ShellCommandGroup注解,并放置在命令所在的包内。那么包中的命令都会分为一组。
这三种方法设置分组,优先级由高到低。

public class UserCommands {
    @ShellCommand(value = "This command ends up in the 'User Commands' group")
    public void foo() {}

    @ShellCommand(value = "This command ends up in the 'Other Commands' group",
            group = "Other Commands")
    public void bar() {}
}

@ShellCommandGroup("Other Commands")
public class SomeCommands {
        @ShellMethod(value = "This one is in 'Other Commands'")
        public void wizz() {}

        @ShellMethod(value = "And this one is 'Yet Another Group'",
                group = "Yet Another Group")
        public void last() {}
}

内置命令

通过spring-shell-starter来创建的应用,都包含一组内置命令。help命令会展示当前系统可用命令。help 会展示命令的详细信息。

覆盖或禁用内置命令了

如果不想用内置命令,那么排除依赖即可。

<dependency>
    <groupId>org.springframework.shell</groupId>
    <artifactId>spring-shell-starter</artifactId>
    <version>2.0.0.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.shell</groupId>
            <artifactId>spring-shell-standard-commands</artifactId>
        </exclusion>
    </exclusion>
</dependency>

禁用特定的命令

如果只想禁用某个命令,那么可以将spring.shell.command..enabled 属性,并设置为false。在启动时,将参数传给系统。下面的demo禁用了help命令。

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		String[] disabledCommands = {"--spring.shell.command.help.enabled=false"};
		String[] fullArgs = StringUtils.concatenateStringArrays(args,disabledCommands);
		SpringApplication.run(DemoApplication.class, fullArgs);
	}
}

覆盖命令

如果想覆盖内置命令,那么实现.Command即可。

public class MyClear implements Clear.Command {

    @ShellCommand("Clear the screen, only better.")
    public void clear() {
        // ...
    }
}

总结

Spring-Shell 基于JLine库提供了提供了REPL模式的控制台交互工具,我们可以通过自定义命令实现控制台命令功能。

参考

[1].https://docs.spring.io/spring-shell/docs/2.0.0.RELEASE/reference/htmlsingle/
[2].https://github.com/spring-projects/spring-shell/issues/190

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值