Spring.Shell.History内置命令覆盖

文章目录

  • 问题
  • 解决方案
    • 覆盖方法
    • 代码
    • yaml配置:指定保存历史命令文件的路径

问题

最近工作上遇到的一个小问题,在Spring Shell中,我们可以自己定义一些命令,已完成我们想要的功能,也可以使用内置命令如help、history、clear。但当一些内置命令达不到我们想要的功能时,就需要对其进行重新。如本次遇到的histroy命令,显示的格式是一个List列表,所有命令在一行。而我想要其以每一条命令一行的格式输出,就需要对其进行覆盖。

解决方案

覆盖方法

  1. 实现History.Command 接口。类路径:org.springframework.shell.standard.commands.History
  2. 添加注解@ShellCommandGroup(“Built-In Commands”), 表示这个是一个内置命令。
  3. 直接复用History中的history方法,保留其原有功能,在这个基础上,将命令每个一行输出。

代码

import org.springframework.shell.standard.commands.History;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

@ShellComponent
@ShellCommandGroup("Built-In Commands")
public class MyHistory implements History.Command {
    private org.jline.reader.History jLineHistory = null;

    public MyHistory(org.jline.reader.History jLineHistory) {
        this.jLineHistory = jLineHistory;
    }
    
	// 函数名要保持不变
    @ShellMethod(value = "Display or save the history of previously run commands")
    public String history(@ShellOption(help = "A file to save history to.", defaultValue = ShellOption.NULL) File file) throws IOException {
        StringBuffer buffer = new StringBuffer();
        if (file == null) {
            jLineHistory.forEach(line -> buffer.append(line).append("
"));
            return buffer.toString();
        } else {
            try (FileWriter w = new FileWriter(file)) {
                for (org.jline.reader.History.Entry entry : jLineHistory) {
                    w.append(entry.line()).append(System.lineSeparator());
                }
            }
            return String.format("Wrote %d entries to %s", jLineHistory.size(), file);
        }
    }
}

org.springframework.shell.standard.commands.History 代码

@ShellComponent
public class History {

    private final org.jline.reader.History jLineHistory;

    public History(org.jline.reader.History jLineHistory) {
        this.jLineHistory = jLineHistory;
    }

    public interface Command {
    }

    @ShellMethod(value = "Display or save the history of previously run commands")
    public List<String> history(@ShellOption(help = "A file to save history to.", defaultValue = ShellOption.NULL) File file) throws IOException {
        if (file == null) {
            List<String> result = new ArrayList<>(jLineHistory.size());
            jLineHistory.forEach(e -> result.add(e.line()));
            return result;
        } else {
            try (FileWriter w = new FileWriter(file)) {
                for (org.jline.reader.History.Entry entry : jLineHistory) {
                    w.append(entry.line()).append(System.lineSeparator());
                }
            }
            return Collections.singletonList(String.format("Wrote %d entries to %s", jLineHistory.size(), file));
        }
    }
}

yaml配置:指定保存历史命令文件的路径

spring:
  main:
    banner-mode: CONSOLE
  shell:
    interactive:
      enabled: true
    history:
      name: log/history.log