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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
38
0
34 703
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

Ах, я должен был упомянуть, что инициализация моей пружины должна произойти после анализа командной строки, так как это зависит от значений из командной строки.

lowellk 25.09.2008 22:07
Ответ принят как подходящий

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

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

 }

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

+1 для статической ссылки. 6 строк кода лучше 20.

Leonel 28.05.2010 15:31

Мне очень понравилось это решение, и я нашел этот необычный способ решить это упражнение: System.out.println ("Args:" + mainContext.getBean ("args")); String [] arg1 = (String []) ((Коллекция) mainContext.getBean ("args")). ToArray (new String [0]); Строка o = arg1 [0]; System.out.println (о);

hephestos 30.06.2012 23:13

Вы также можете передать массив объектов в качестве второго параметра в 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;
    }

}

вместе с:

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

}

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

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

И если вы удачливый разработчик 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

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

Это должен быть правильный способ сделать это. У меня он отлично работает.

johnlinp 31.03.2020 04:27

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

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

Другие вопросы по теме