Работа с аргументами командной строки и Spring - PullRequest
36 голосов
/ 25 сентября 2008

Когда я пишу приложение командной строки Spring, которое анализирует аргументы командной строки, как мне передать их в Spring? Хотел бы я, чтобы мой main () был структурирован так, чтобы он сначала анализировал аргументы командной строки, а затем в Spring? Тем не менее, как бы он передал объект, содержащий разобранные аргументы, в Spring?

Ответы [ 6 ]

39 голосов
/ 25 сентября 2008

Две возможности, которые я могу придумать.

1) Установите статическую привязку. (Статическая переменная, хотя обычно вызывает недовольство, в этом случае работает нормально, потому что может быть только 1 вызов командной строки)

public class MyApp {
  public static String[] ARGS; 
  public static void main(String[] args) {
    ARGS = args;
      // create context
  }
}

Затем вы можете ссылаться на аргументы командной строки в Spring с помощью:

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

В качестве альтернативы (если вы полностью против статических переменных), вы можете:

2) Программно добавить аргументы в контекст приложения:

 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"
   };

 }

Разбор аргументов командной строки оставлен читателю в качестве упражнения.

6 голосов
/ 15 января 2010

Взгляните на мою библиотеку Spring-CLI - на http://github.com/sazzer/spring-cli - как один из способов сделать это. Он предоставляет вам основной класс, который автоматически загружает контексты пружины и имеет возможность использовать Commons-CLI для автоматического анализа аргументов командной строки и внедрения их в ваши bean-компоненты.

5 голосов
/ 20 ноября 2008

Вы также можете передать массив объектов в качестве второго параметра в getBean, который будет использоваться в качестве аргументов для конструктора или фабрики.

public static void main(String[] args) {
   Mybean m = (Mybean)context.getBean("mybean", new Object[] {args});
}
4 голосов
/ 27 января 2017

Начиная с Spring 3.1, нет необходимости в каком-либо пользовательском коде, предложенном в других ответах. Проверьте CommandLinePropertySource , это обеспечивает естественный способ вставки аргументов CL в ваш контекст.

А если вы счастливый разработчик Spring Boot, вы можете упростить свой код на один шаг вперед, используя тот факт, что SpringApplication дает вам следующее:

По умолчанию класс выполнит следующие шаги для начальной загрузки вашего Применение:

...

Зарегистрируйте CommandLinePropertySource для предоставления аргументов командной строки как Spring properties

А если вас интересует порядок разрешения свойств Spring Boot, обратитесь к этой странице .

3 голосов
/ 28 июля 2009

Рассмотрим следующий класс:

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"));

}
1 голос
/ 25 сентября 2008

Вот пример загрузки пружинного ремешка для метода Main, просто возьмите переданные параметры как обычно, а затем заставьте функцию, которую вы вызываете для вашего компонента (в случае 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;
}
...