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?
Réponses
Trop de publicités?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.
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.
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"));
}
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;
}