目錄
概述
官網: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://blog.csdn.net/zknxx/article/details/52196427 SpringBoot之CommandLineRunner介面和ApplicationRunner介面
https://www.jianshu.com/p/5d4ffe267596 CommandLineRunner或者ApplicationRunner介面