您的位置:首页 > 编程语言 > Java开发

自定义Spring Shell

2019-06-24 22:52 2191 查看

目录

  • 自定义命令提示符
  • 自定义命令行选项行为
  • 自定义参数转换器
  • 概述

    官网:https://projects.spring.io/spring-shell/

    Spring Shell除了提供一些常用的内置命令之外,还允许开发者对一些默认功能进行定制。

    自定义内置命令

    禁用内置命令

    禁用Spring Shell的内置命令非常简单,只需要在pom.xml文件中进行简单配置即可,如下所示:

    <!-- Spring Shell -->
    <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>
    </exclusions>
    </dependency>
    shell:>help
    No command found for 'help'
    shell:>exit
    No command found for 'exit'
    shell:>

    完全禁用了所有内置命令之后,将无法通过

    help
    命令查询其他命令信息,也不能再使用
    exit
    命令退出应用。
    因此,如果有需要的情况下,应该只是禁用某些内置命令。

    如果需要禁用指定内置命令,需要在代码中设置对应的命令属性为false,格式为:

    spring.shell.command.<command>.enabled=true

    例如,需要禁用
    help
    命令:

    @SpringBootApplication
    public class TestSpringshellApplication {
    public static void main(String[] args) {
    String[] disabledCommands = new String[]{"--spring.shell.command.help.enabled=false"};
    String[] fullArgs = StringUtils.concatenateStringArrays(args, disabledCommands);
    SpringApplication.run(TestSpringshellApplication.class, fullArgs);
    }
    }
    # help命令将不再能使用
    shell:>help
    No command found for 'help'
    Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.
    shell:>exit

    如果禁用的是其他命令,如:

    clear
    ,在Spring Shell应用启动之后通过
    help
    命令不再能看被禁用的命令了。

    @SpringBootApplication
    public class TestSpringshellApplication {
    public static void main(String[] args) {
    // 禁用了内置的clear命令
    String[] disabledCommands = new String[]{"--spring.shell.command.clear.enabled=false"};
    String[] fullArgs = StringUtils.concatenateStringArrays(args, disabledCommands);
    SpringApplication.run(TestSpringshellApplication.class, fullArgs);
    }
    }
    shell:>help
    AVAILABLE COMMANDS
    
    Built-In Commands
    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.

    显然,在禁用了指定的内置命令之后,通过

    help
    命令将不能看到该命令了。

    覆盖内置命令

    如果希望重写内置命令的实现,可以通过实现接口

    org.springframework.shell.standard.commands.<Command>.Command
    来完成(如:需要重写clear命令的实现,实现接口
    org.springframework.shell.standard.commands.Clear.Command
    )。
    如下为重写内置命令script的实现:

    import org.springframework.shell.standard.ShellComponent;
    import org.springframework.shell.standard.ShellMethod;
    import org.springframework.shell.standard.commands.Script;
    // 实现接口org.springframework.shell.standard.commands.Script.Command
    @ShellComponent
    public class MyScript implements Script.Command {
    // 注意:命令名称与内置命令保持一致
    @ShellMethod("Read and execute commands from a file.")
    public void script() {
    / // 实现自定义逻辑
    System.out.println("override default script command");
    }
    }

    有意思的是,此时在内置命令“Built-In Commands”分组中将不能看到

    script
    命令了,而是在自定义的分组中,

    shell:>help
    AVAILABLE COMMANDS
    
    Built-In Commands  # 在内置命令分组中看不到重写的命令了
    clear: Clear the shell screen.
    exit, quit: Exit the shell.
    help: Display help about available commands.
    stacktrace: Display the full stacktrace of the last error.
    
    My Script          # 重写的命令此时在自定义分组中
    scriptdo: Read and execute commands from a file.

    如果希望被覆盖的内置命令依然能够在“Built-In Commands”分组中看到,可以通过注解

    @ShellMethod
    的group属性指定。

    // 指定被覆盖的内置命令分组为“Built-In Commands”
    @ShellMethod(value = "Read and execute commands from a file.", group = "Built-In Commands")
    public void script() {
    System.out.println("override default script command");
    }
    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.
    
    shell:>script
    override default script command

    自定义命令提示符

    默认情况下,Spring Shell启动之后显示的是一个黄色的命令提示符(

    shell:>
    )等待用户输入。
    可以通过Spring Shell提供的接口
    org.springframework.shell.jline.PromptProvider
    对该命令提示符进行定制。

    // 通过实现接口org.springframework.shell.jline.PromptProvider定制命令提示符
    import org.jline.utils.AttributedString;
    import org.jline.utils.AttributedStyle;
    import org.springframework.shell.jline.PromptProvider;
    import org.springframework.stereotype.Component;
    @Component
    public class MyPromptProvider implements PromptProvider {
    @Override
    public AttributedString getPrompt() {
    // 定制命令提示符为红色的“#”
    return new AttributedString("#", AttributedStyle.DEFAULT.foreground(AttributedStyle.RED));
    }
    }

    如下为定制的命令提示符:

    自定义命令行选项行为

    Spring Shell提供了2个默认的

    ApplicationRunner
    ,用于实现命令行选项的行为。

    1.

    InteractiveShellApplicationRunner
    用于启动交互式界面,接收用户输入命令。
    2.
    ScriptShellApplicationRunner
    用于在应用启动时从程序参数中读取指定文件中的命令并执行,具体来讲:将多个命令写在文件中,并通过参数的形式将包含了批量命令的文件路径传递给程序,传递的文件路径参数必须以“@”开始,如下示例:

    $ java -jar /home/test/sun/workspace/test-springshell/target/test-springshell-0.0.1-SNAPSHOT.jar @/home/test/cmd

    文件

    /home/test/cmd
    中的内容为:

    $ cat /home/test/cmd
    help

    这样,在启动程序时,将会自动执行

    /home/test/cmd
    文件中的命令(如果文件不存在,启动应用时报错)。
    值得注意的是: 当在程序参数中存在“@local_file_path”这样的参数时,应用启动后执行完文件“local_file_path”内命令之后就退出了,不会进入交互式命令行界面(上述示例中,应用启动后执行
    help
    命令之后就退出了)。

    如果Spring Shell默认提供的上述2个

    ApplicationRunner
    无法满足需求,可以自定义其他的命令行选项行为,直接实现接口
    org.springframework.boot.ApplicationRunner
    即可。

    自定义参数转换器

    默认情况下,Spring Shell使用标准的Spring类型转换机制将命令行的文本参数转换为指定的类型。
    实际上,Spring Shell是通过

    DefaultConversionService
    注册
    Converter<S, T>
    GenericConverter
    或者
    ConverterFactory<S, R>
    类型的Bean对象来实现对命令行参数进行类型转换的。

    换句话说,如果我们需要自定义类型转换器,只需要简单实现接口

    org.springframework.core.convert.converter.Converter<S, T>
    就可以了。

    // 自定义类型
    public class Food {
    private String value = null;
    public Food(String value) {
    this.value = value;
    }
    
    @Override
    public String toString() {
    return new StringBuilder()
    .append("Food{").append("value='").append(value).append("'}")
    .toString();
    }
    }
    
    // 自定义类型转换器
    @Component
    public class MyConverter implements Converter<String, Food> {
    @Override
    public Food convert(String s) {
    // 将输入参数转换为Food类型实例
    return new Food(s);
    }
    }
    
    // 使用自定义转换类型
    @ShellComponent
    public class ConvertionCmd {
    // 在命令方法中直接可以获取Food对象,这是通过前面的自定义类型转换器MyConverter实现的
    @ShellMethod("Conversion food")
    public String food(Food food) {
    return food.toString();
    }
    }

    在命令行指定命令

    food

    #food apple
    Food{value='apple'}

    显然,通过自定义类型转换器可以实现对命令参数的特殊处理,非常实用。

    【参考】
    https://www.geek-share.com/detail/2682016548.html SpringBoot之CommandLineRunner接口和ApplicationRunner接口
    https://www.jianshu.com/p/5d4ffe267596 CommandLineRunner或者ApplicationRunner接口

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: