自定義Spring Shell

目錄

概述

官網:https://projects.spring.io/spring-shell/html

Spring Shell除了提供一些經常使用的內置命令以外,還容許開發者對一些默認功能進行定製。java

自定義內置命令

禁用內置命令

禁用Spring Shell的內置命令很是簡單,只須要在pom.xml文件中進行簡單配置便可,以下所示:spring

<!-- 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命令退出應用。
所以,若是有須要的狀況下,應該只是禁用某些內置命令。shell

若是須要禁用指定內置命令,須要在代碼中設置對應的命令屬性爲false,格式爲:spring.shell.command.<command>.enabled=true
例如,須要禁用help命令:app

@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命令再也不能看被禁用的命令了。ide

@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命令將不能看到該命令了。ui

覆蓋內置命令

若是但願重寫內置命令的實現,能夠經過實現接口org.springframework.shell.standard.commands.<Command>.Command來完成(如:須要重寫clear命令的實現,實現接口org.springframework.shell.standard.commands.Clear.Command)。
以下爲重寫內置命令script的實現:this

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命令了,而是在自定義的分組中,spa

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屬性指定。.net

// 指定被覆蓋的內置命令分組爲「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定製命令提示符

自定義命令行選項行爲

Spring Shell提供了2個默認的ApplicationRunner,用於實現命令行選項的行爲。
Spring Shell實現的AppicationRunner

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對象來實現對命令行參數進行類型轉換的。
註冊Spring Shell類型轉換器

換句話說,若是咱們須要自定義類型轉換器,只須要簡單實現接口org.springframework.core.convert.converter.Converter<S, T>就能夠了。
Spring Shell的類型轉化器

// 自定義類型
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'}

顯然,經過自定義類型轉換器能夠實現對命令參數的特殊處理,很是實用。

【參考】
http://www.javashuo.com/article/p-hsvrdiyq-ce.html SpringBoot之CommandLineRunner接口和ApplicationRunner接口
https://www.jianshu.com/p/5d4ffe267596 CommandLineRunner或者ApplicationRunner接口

個人博客即將同步至騰訊雲+社區,邀請你們一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=33hxmqpel3wgg

相關文章
相關標籤/搜索