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