39 votes

Gérer les arguments de ligne de commande et Spring

Lorsque j'écris une application de ligne de commande Spring qui analyse les arguments de ligne de commande, comment les transmettre à Spring? Voudrais-je avoir mon principal () structuré de sorte qu'il analyse d'abord les arguments de la ligne de commande, puis son printemps? Même ainsi, comment passerait-il l'objet tenant les arguments analysés à Spring?

40voto

flicken Points 5887

Deux possibilités, je pense.

1) Définir un point de référence fixe. (Une variable statique, bien que généralement mal vu, est OK dans ce cas, car il ne peut y avoir 1 ligne de commande d'invocation).

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

Vous pouvez alors faire référence à la ligne de commande arguments au Printemps par le biais de:

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

Sinon (si vous êtes tout à fait opposé à des variables statiques), vous pouvez:

2) ajouter par la args le contexte de l'application:

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

}

L'analyse des arguments de ligne de commande est laissé comme exercice au lecteur.

7voto

Graham Points 617

Jetez un œil à ma bibliothèque Spring-CLI - à http://github.com/sazzer/spring-cli - comme moyen de le faire. Il vous donne une classe principale qui charge automatiquement les contextes de printemps et a la possibilité d'utiliser Commons-CLI pour analyser automatiquement les arguments de ligne de commande et les injecter dans vos beans.

5voto

BeWarned Points 1314

Vous pouvez également passer un tableau d'objets comme second paramètre à getBean qui sera utilisé comme arguments pour le constructeur ou la fabrique.

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

3voto

Brian Dilley Points 985

Considérez la classe suivante:

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

}
 

de même que:

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

}
 

1voto

Bradley Beddoes Points 31

Voici un exemple pour démarrer le ressort de sangle pour une méthode Main, saisissez simplement les paramètres passés comme d'habitude, puis faites en sorte que la fonction que vous appelez sur votre bean (dans le cas deployer.execute ()) les prenne comme des chaînes ou via n'importe quel format que vous jugez approprié .

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X