Java 处理命令行参数和Spring

Java 处理命令行参数和Spring,java,spring,command-line,Java,Spring,Command Line,当我编写一个Spring命令行应用程序来解析命令行参数时,我如何将它们传递给Spring?我是否希望将main()结构化,以便它首先解析命令行args,然后初始化Spring?即便如此,它如何将保存已解析参数的对象传递给Spring?这里是一个引导Spring的示例,对于一个主方法,只需正常获取传递的参数,然后让您在bean上调用的函数(在deployer.execute()中)将其作为字符串或通过您认为合适的任何格式 public static void main(String[] args)

当我编写一个Spring命令行应用程序来解析命令行参数时,我如何将它们传递给Spring?我是否希望将main()结构化,以便它首先解析命令行args,然后初始化Spring?即便如此,它如何将保存已解析参数的对象传递给Spring?

这里是一个引导Spring的示例,对于一个主方法,只需正常获取传递的参数,然后让您在bean上调用的函数(在deployer.execute()中)将其作为字符串或通过您认为合适的任何格式

public static void main(String[] args) throws IOException, ConfigurationException {
    Deployer deployer = bootstrapSpring();

    deployer.execute();
}

private static Deployer bootstrapSpring()
{
    FileSystemXmlApplicationContext appContext = new FileSystemXmlApplicationContext("spring/deployerContext.xml");

    Deployer deployer = (Deployer)appContext.getBean("deployer");
    return deployer;
}

我能想到两种可能性

1) 设置一个静态引用。(虽然通常不赞成使用静态变量,但在这种情况下是可以的,因为只有一个命令行调用)

然后,您可以通过以下方式引用Spring中的命令行参数:

<util:constant static-field="MyApp.ARGS"/>

解析命令行参数留给读者作为练习

还可以将对象数组作为第二个参数传递给
getBean
,该参数将用作构造函数或工厂的参数

public static void main(String[] args) {
   Mybean m = (Mybean)context.getBean("mybean", new Object[] {args});
}

考虑以下类别:

public class ExternalBeanReferneceFactoryBean 
    extends AbstractFactoryBean
    implements BeanNameAware {

    private static Map<String, Object> instances = new HashMap<String, Object>();
    private String beanName;

    /**
     * @param instance the instance to set
     */
    public static void setInstance(String beanName, Object instance) {
        instances.put(beanName, instance);
    }

    @Override
    protected Object createInstance() 
        throws Exception {
        return instances.get(beanName);
    }

    @Override
    public Class<?> getObjectType() {
        return instances.get(beanName).getClass();
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

}

查看一下我的SpringCLI库-at-作为实现这一点的一种方法。它为您提供了一个自动加载spring上下文的主类,并且能够使用Commons CLI自动解析命令行参数并将它们注入到bean中。

从spring 3.1开始,不需要其他答案中建议的任何自定义代码。检查,它提供了一种将CL参数注入上下文的自然方式

如果您是一名幸运的Spring Boot开发人员,您可以利用以下事实进一步简化代码:

默认情况下,类将执行以下步骤来引导 应用程序:

注册CommandLinePropertySource以公开命令行参数 作为弹簧特性


如果您对Spring Boot属性解析顺序感兴趣,请咨询。

我不确定您到底想实现什么,也许您可以添加一些关于命令和参数的详细信息,以及您希望从应用程序中得到什么结果

我认为这不是您需要的,但它可能会帮助其他读者:Spring支持使用双连字符从命令行接收属性(例如
java-jarapp.jar--my.property=“property Value”
有关更多信息,请参阅本文档:

啊,我应该提到,我的spring初始化必须在命令行被解析之后进行,因为静态引用依赖于命令行+1中的值。6行代码比20行代码好。我非常喜欢这个解决方案,并找到了这个古怪的方法来解决这个问题:System.out.println(“Args:+mainContext.getBean”)(“args”);String[]arg1=(String[])((Collection)mainContext.getBean(“args”)).toArray(新字符串[0]);String o=arg1[0];System.out.println(o);这应该是正确的方法。它对我来说非常适合。
public static void main(String[] args) {
   Mybean m = (Mybean)context.getBean("mybean", new Object[] {args});
}
public class ExternalBeanReferneceFactoryBean 
    extends AbstractFactoryBean
    implements BeanNameAware {

    private static Map<String, Object> instances = new HashMap<String, Object>();
    private String beanName;

    /**
     * @param instance the instance to set
     */
    public static void setInstance(String beanName, Object instance) {
        instances.put(beanName, instance);
    }

    @Override
    protected Object createInstance() 
        throws Exception {
        return instances.get(beanName);
    }

    @Override
    public Class<?> getObjectType() {
        return instances.get(beanName).getClass();
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

}
/**
 * Starts the job server.
 * @param args command line arguments
 */
public static void main(String[] args) {

    // parse the command line
    CommandLineParser parser = new GnuParser();
    CommandLine cmdLine = null;
    try {
        cmdLine = parser.parse(OPTIONS, args);
    } catch(ParseException pe) {
        System.err.println("Error parsing command line: "+pe.getMessage());
        new HelpFormatter().printHelp("command", OPTIONS);
        return;
    }

    // create root beanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

    // register bean definition for the command line
    ExternalBeanReferneceFactoryBean.setInstance("commandLine", cmdLine);
    beanFactory.registerBeanDefinition("commandLine", BeanDefinitionBuilder
        .rootBeanDefinition(ExternalBeanReferneceFactoryBean.class)
        .getBeanDefinition());

    // create application context
    GenericApplicationContext rootAppContext = new GenericApplicationContext(beanFactory);
    rootAppContext.refresh();

    // create the application context
    ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { 
        "/commandlineapp/applicationContext.xml"
    }, rootAppContext);

    System.out.println(appContext.getBean("commandLine"));

}