Der Umgang mit Kommandozeilenargumenten und Spring
-
02-07-2019 - |
Frage
Wenn ich eine Feder Kommandozeilen-Anwendung zu schreiben, die Befehlszeilenargumente analysiert, wie gehe ich sie zum Frühling? Würde ich möchte, dass meine main () aufgebaut haben, so dass es zuerst die args Befehlszeile analysiert und dann inits Spring? Auch so, wie wäre es, das Objekt übergeben Sie die geparsten args hält zum Frühling?
Lösung
Zwei Möglichkeiten kann ich mir vorstellen.
1) Legen Sie eine statische Referenz. (Eine statische Variable, obwohl bei der typischerweise Stirnrunzelnd ist in diesem Fall in Ordnung, da es nur 1-Befehlszeilenaufruf sein kann).
public class MyApp {
public static String[] ARGS;
public static void main(String[] args) {
ARGS = args;
// create context
}
}
Sie können dann die Befehlszeilenargumente im Frühjahr Referenz über:
<util:constant static-field="MyApp.ARGS"/>
Als Alternative (wenn Sie völlig entgegengesetzt statischen Variablen sind), können Sie:
2) in Programmatically die args zu dem Anwendungskontext:
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"
};
}
Das Parsen die Befehlszeilenargumente wird als Übung dem Leser überlassen.
Andere Tipps
Haben Sie einen Blick auf meine Frühlings-CLI-Bibliothek - unter http://github.com/sazzer/spring -cli - als eine Möglichkeit, dies zu tun. Es gibt Ihnen eine Hauptklasse, die automatisch Feder Kontexte lädt und hat die Fähigkeit, automatisch für das Parsen von Befehlszeilenargumenten Commons-CLI zu verwenden und sie in Ihre Bohnen injiziert wird.
Sie können auch ein Object-Array als zweiter Parameter übergeben getBean
, die als Argumente an den Konstruktor oder der Fabrik verwendet werden.
public static void main(String[] args) {
Mybean m = (Mybean)context.getBean("mybean", new Object[] {args});
}
Ab Frühling 3.1 besteht keine Notwendigkeit, in jedem benutzerdefinierten Code in anderen Antworten vorgeschlagen. Prüfen Sie CommandLinePropertySource , hat es eine natürliche Art und Weise liefert CL Argumente in Ihren Kontext zu injizieren.
Und wenn Sie ein glücklicher Frühlings-Boot-Entwickler sind, könnten Sie Ihren Code ein Schritt nach vorn nutzt die Tatsache vereinfachen, die a href <= "http://docs.spring.io/spring-boot/docs/current/api/org /springframework/boot/SpringApplication.html“rel = "nofollow noreferrer"> SpringApplication gibt Ihnen folgende Möglichkeiten:
Mit dem Standardklasse werden die folgenden Schritte durchführen, um Bootstrap Ihre Anwendung:
...
Registrieren eines CommandLinePropertySource auf Befehlszeilenargumente aussetzen als Federeigenschaften
Und wenn Sie sich für das Frühjahr Boot-Eigenschaft Auflösung sind, um wenden Sie sich bitte diese Seite .
Betrachten Sie die folgende Klasse:
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;
}
}
zusammen mit:
/**
* 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"));
}
Hier ist ein Beispiel Band Feder für ein Hauptverfahren zu starten, einfach die übergebenen params greifen als normal dann die Funktion, die Sie auf Ihrem Bean Anruf (im Fall deployer.execute ()) nehmen sie als Strings oder über ein beliebiges Format Sie fühlen geeignet.
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;
}