目录
概述
自定义内置命令
禁用内置命令
覆盖内置命令
自定义命令提示符
自定义命令行选项行为
自定义参数转换器
概述
官网: 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'
- }
显然, 通过自定义类型转换器可以实现对命令参数的特殊处理, 非常实用.
[参考]
SpringBoot 之 CommandLineRunner 接口和 ApplicationRunner 接口
https://www.jianshu.com/p/5d4ffe267596 CommandLineRunner 或者 ApplicationRunner 接口
来源: https://www.cnblogs.com/nuccch/p/11080056.html