Подтвердить что ты не робот

Работа с аргументами командной строки и Spring

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

4b9b3361

Ответ 1

Я могу придумать две возможности.

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 in the context
     System.out.println("Args: " + mainContext.getBean("args"));
   }

   private static String[] CONFIG_LOCATIONS = new String[] {
     "applicationContext.xml"
   };

 }

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

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

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

...

Зарегистрируйте CommandLinePropertySource, чтобы вывести аргументы командной строки как Spring свойства

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

Ответ 5

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

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

}

Ответ 6

Вот пример загрузки ремешка 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;
}

Ответ 7

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

Я думаю, что это не то, что вам нужно, но это может помочь другим читателям: 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