如何在 spring boot remote shell 中将参数和选项传递给自定义 remote shell 命令?

How to pass arguments and options to custom remote shell command in spring boot remote shell?

这是

的后续问题

根据对上述问题的建议,我正在尝试 spring 远程启动 shell。

我已经按照此文档创建了自定义命令,

http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-remote-shell.html#production-ready-extending-the-remote-shell

但在现实世界的用例中,我们大多有参数和选项来命令。文档中没有提及如何定义它们,以便用户在 运行ning 命令时应该通过。

这在 spring-shell.

中解释得很好并且很容易做到

http://docs.spring.io/spring-shell/docs/current/reference/htmlsingle/#simple-application

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

但是我们不能在 spring 启动时使用 spring shell。

针对此类用例的可靠生产就绪解决方案是什么?

更新:

在 CRaSH 文档上找到了解决方案

http://www.crashub.org/1.3/reference.html#developping_commands

我可以在登录 shell 后在命令列表中看到 myCommand,但是当我 运行 命令时,

但我遇到异常

"Could not create command commandName instance".

我正在尝试在命令中使用 spring bean,所以我进行了自动装配,例如

package commands;

import org.crsh.cli.Argument;
import org.crsh.cli.Command;
import org.crsh.cli.Usage;
import org.crsh.cli.Option;
import org.crsh.cli.Required;
import org.crsh.command.BaseCommand;
import org.crsh.command.InvocationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


@Usage("My test computation commands.")
public class myCommand extends BaseCommand {

    protected final Logger log = LoggerFactory.getLogger(getClass());

    /**
     * 
     */
    public Service1 service1;

    /**
     * 
     */
    public Service2 service2;

    /**
     * @param service1
     * @param service2
     */
    @Autowired
    public myCommand(Service1 service1, Service2 service2) {
        super();
        this.service1 = service1;
        this.service2 = service2;
    }


    @Usage("Test command")
    @Command
    public Map<String, Double> command1(InvocationContext<Object> context, @Usage("id") @Required @Argument int id)
            throws Exception {


        Map<String, Double> result = new HashMap<>();

        result.put("key1", service1.compute(id));
        result.put("key2", service2.compute(id));

        return result;

    }

}

我认为您不能在远程 shell 命令中注入 bean。

然而,您可以将 InvocationContext 注入到您的方法中,并使用它从您的上下文中检索 spring 托管 bean:

@Usage('Example using spring.beanfactory')
@Command
def mycommand(InvocationContext context, ...) {
    BeanFactory beans = context.attributes['spring.beanfactory']
    YourBean bean = beans.getBean(YourBean.class);
    ...
}

一个对我有用的完整示例:

package commands

import org.crsh.cli.Command
import org.crsh.cli.Usage
import org.crsh.command.InvocationContext
import org.springframework.beans.factory.BeanFactory
import com.alexbt.goodies.MyBean

class SayMessage {
    String message;
    SayMessage(){
        this.message = "Hello";
    }

    @Usage("Default command")
    @Command
    def main(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
        BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
        MyBean bean = beanFactory.getBean(MyBean.class);
        return message + " " + bean.getValue() + " " + param;
    }

    @Usage("Hi subcommand")
    @Command
    def hi(InvocationContext context, @Usage("A Parameter") @Option(names=["p","param"]) String param) {
        BeanFactory beanFactory = (BeanFactory) context.getAttributes().get("spring.beanfactory");
        MyBean bean = beanFactory.getBean(MyBean.class);
        return "Hi " + bean.getValue() + " " + param;
    }
}

> saymsg -p Johnny
> Hello my friend Johnny

> saymsg hi -p Johnny
> Hi my friend Johnny