Dealing with command line arguments and Spring

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.


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).

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:

<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:

 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.


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.

And if you are a lucky Spring Boot developer you could simplify your code one step forward leveraging the fact that SpringApplication gives you the following:

By default class will perform the following steps to bootstrap your application:

...

Register a CommandLinePropertySource to expose command line arguments as Spring properties

And if you are interested in the Spring Boot property resolution order please consult this page.