コマンドライン引数を解析するSpringコマンドラインアプリケーションを作成している場合、それらをSpringに渡すにはどうすればよいですか?main()を構造化して、最初にコマンドライン引数を解析してからSpringを初期化するようにしますか?それでも、解析された引数を保持しているオブジェクトをSpringに渡すにはどうすればよいでしょうか。
7 に答える
私が考えることができる2つの可能性。
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"
};
}
コマンド ライン引数の解析は、読者の課題として残されています。
Have a look at my Spring-CLI library - at http://github.com/sazzer/spring-cli - as one way of doing this. It gives you a main class that automatically loads spring contexts and has the ability to use Commons-CLI for parsing command line arguments automatically and injecting them into your beans.
Spring 3.1 以降、他の回答で提案されているカスタム コードは必要ありません。CommandLinePropertySourceを確認してください。CL 引数をコンテキストに挿入する自然な方法を提供します。
また、幸運な Spring Boot 開発者であれば、 SpringApplicationが次のことを提供するという事実を利用して、コードを一歩前進させることができます。
デフォルトでは、クラスは次の手順を実行してアプリケーションをブートストラップします。
...
CommandLinePropertySource を登録して、コマンドライン引数を Spring プロパティとして公開する
また、Spring Boot のプロパティ解決順序に興味がある場合は、このページを参照してください。
Object配列getBean
を、コンストラクターまたはファクトリへの引数として使用される2番目のパラメーターとして渡すこともできます。
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"));
}
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;
}
正確に何を達成しようとしているのかわかりません。コマンドと引数がどのように見えるか、アプリケーションに期待する結果について詳細を追加できるかもしれません。
これはあなたが必要としているものではないと思いますが、他の読者の助けになるかもしれません: 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