【问题标题】:How to pass arguments and options to custom remote shell command in spring boot remote shell?如何在 Spring Boot 远程 shell 中将参数和选项传递给自定义远程 shell 命令?
【发布时间】:2016-09-28 14:36:29
【问题描述】:

这是关于

的后续问题

how to build console command in spring boot web application using spring shell?

根据上述问题的建议,我正在尝试使用 spring boot 远程 shell。

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

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

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

这在 spring-shell 中得到了很好的解释并且很容易做到。

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

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

但我们不能将 spring shell 与 spring boot 一起使用。

对于此类用例,有哪些可靠的生产就绪解决方案?

更新:

在 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;

    }

}

【问题讨论】:

    标签: java spring spring-boot crash-shell


    【解决方案1】:

    我认为您不能在远程 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
    

    【讨论】:

    • 谢谢,是的,我试过了,但没有一个 Java 命令示例使用 beanfactory 来获取 bean。不确定什么是正确的语法。在这里使用 groovy 比使用 java 有什么优势吗?
    • BeanFactory beans = context.getAttributes().get("spring.beanfactory"); MyService myService = beans.getBean(MyService.class);
    猜你喜欢
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多