Java 处理命令行参数和 Spring
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/132231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dealing with command line arguments and Spring
提问by lowellk
When I'm writing a Spring command line application which parses command line arguments, how do I pass them to Spring? Would I want to have my main() structured so that it first parses the command line args and then inits Spring? Even so, how would it pass the object holding the parsed args to Spring?
当我编写解析命令行参数的 Spring 命令行应用程序时,如何将它们传递给 Spring?我是否想让我的 main() 结构化,以便它首先解析命令行参数,然后初始化 Spring?即便如此,它如何将包含已解析参数的对象传递给 Spring?
采纳答案by flicken
Two possibilities I can think of.
我能想到的两种可能。
1) Set a static reference. (A static variable, although typically frowned upon, is OK in this case, because there can only be 1 command line invocation).
1) 设置静态引用。(静态变量,虽然通常不赞成,但在这种情况下是可以的,因为只能有 1 个命令行调用)。
public class MyApp {
public static String[] ARGS;
public static void main(String[] args) {
ARGS = args;
// create context
}
}
You can then reference the command line arguments in Spring via:
然后,您可以通过以下方式在 Spring 中引用命令行参数:
<util:constant static-field="MyApp.ARGS"/>
Alternatively (if you are completely opposed to static variables), you can:
或者(如果您完全反对静态变量),您可以:
2) Programmatically add the args to the application context:
2) 以编程方式将 args 添加到应用程序上下文中:
public class MyApp2 {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// Define a bean and register it
BeanDefinition beanDefinition = BeanDefinitionBuilder.
rootBeanDefinition(Arrays.class, "asList")
.addConstructorArgValue(args).getBeanDefinition();
beanFactory.registerBeanDefinition("args", beanDefinition);
GenericApplicationContext cmdArgCxt = new GenericApplicationContext(beanFactory);
// Must call refresh to initialize context
cmdArgCxt.refresh();
// Create application context, passing command line context as parent
ApplicationContext mainContext = new ClassPathXmlApplicationContext(CONFIG_LOCATIONS, cmdArgCxt);
// See if it's in the context
System.out.println("Args: " + mainContext.getBean("args"));
}
private static String[] CONFIG_LOCATIONS = new String[] {
"applicationContext.xml"
};
}
Parsing the command line arguments is left as an exercise to the reader.
解析命令行参数留给读者作为练习。
回答by Bradley Beddoes
Here is an example to boot strap spring for a Main method, simply grab the passed params as normal then make the function you call on your bean (in the case deployer.execute()) take them as Strings or via any format you feel suitable.
这是一个 Main 方法的启动带 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;
}
回答by BeWarned
You can also pass an Object array as a second parameter to getBean
which will be used as arguments to the constructor or factory.
您还可以将 Object 数组作为第二个参数传递给getBean
它,该参数将用作构造函数或工厂的参数。
public static void main(String[] args) {
Mybean m = (Mybean)context.getBean("mybean", new Object[] {args});
}
回答by Brian Dilley
Consider the following class:
考虑以下类:
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;
}
}
along with:
随着:
/**
* 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"));
}
回答by Graham
Have a look at my Spring-CLI library - at http://github.com/sazzer/spring-cli- as one way of doing this. It gives you a main class that automatically loads spring contexts and has the ability to use Commons-CLI for parsing command line arguments automatically and injecting them into your beans.
看看我的 Spring-CLI 库 - 在http://github.com/sazzer/spring-cli- 作为这样做的一种方式。它为您提供了一个自动加载 spring 上下文的主类,并能够使用 Commons-CLI 自动解析命令行参数并将它们注入到您的 bean 中。
回答by Sergey Pauk
Starting from Spring 3.1 there is no need in any custom code suggested in other answers. Check CommandLinePropertySource, it provides a natural way to inject CL arguments into your context.
从 Spring 3.1 开始,不需要其他答案中建议的任何自定义代码。检查CommandLinePropertySource,它提供了一种将 CL 参数注入上下文的自然方式。
And if you are a lucky Spring Boot developer you could simplify your code one step forward leveraging the fact that SpringApplicationgives you the following:
如果您是一名幸运的 Spring Boot 开发人员,您可以利用SpringApplication为您提供以下功能的事实进一步简化您的代码:
By default class will perform the following steps to bootstrap your application:
...
Register a CommandLinePropertySource to expose command line arguments as Spring properties
默认情况下,类将执行以下步骤来引导您的应用程序:
...
注册 CommandLinePropertySource 以将命令行参数公开为 Spring 属性
And if you are interested in the Spring Boot property resolution order please consult this page.
如果您对 Spring Boot 属性解析顺序感兴趣,请参阅此页面。
回答by Gerardo Roza
I'm not sure what you are trying to achieve exactly, maybe you can add some details on what the command and the arguments will look like, and what outcome you expect from your application.
我不确定您想要达到的确切目标,也许您可以添加一些有关命令和参数的外观以及您对应用程序的期望结果的详细信息。
I think this is not what you need, but it might help other readers: Spring supports receiving properties from the command line using double hyphen (e.g. java -jar app.jar --my.property="Property Value"
Have a look at this documentation for more information:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-command-line-args
我认为这不是您需要的,但它可能对其他读者有所帮助:Spring 支持使用双连字符从命令行接收属性(例如,java -jar app.jar --my.property="Property Value"
查看此文档以获取更多信息:https:
//docs.spring.io/spring -boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-command-line-args