2008-09-25 19 views
35

से निपटने पर जब मैं एक स्प्रिंग कमांड लाइन एप्लिकेशन लिख रहा हूं जो कमांड लाइन तर्कों को पार करता है, तो मैं उन्हें वसंत में कैसे पास करूं? क्या मैं अपना मुख्य() संरचित करना चाहता हूं ताकि यह पहले कमांड लाइन तर्कों को पार कर सके और फिर स्प्रिंग में प्रवेश करे? फिर भी, यह स्प्रिंग में पार्स किए गए तर्कों को रखने वाले ऑब्जेक्ट को कैसे पास करेगा?कमांड लाइन तर्क और वसंत

उत्तर

38

दो संभावनाएं जिनके बारे में मैं सोच सकता हूं।

1) एक स्थिर संदर्भ सेट करें। (एक स्थैतिक चर, हालांकि आम तौर पर फंसे हुए, इस मामले में ठीक है, क्योंकि केवल 1 कमांड लाइन आमंत्रण हो सकता है)।

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

फिर आप वसंत में आदेश पंक्ति तर्क संदर्भित कर सकते हैं के माध्यम से:

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

} 

कमांड लाइन तर्क को पार्स करना पाठक को अभ्यास के रूप में छोड़ दिया जाता है।

+4

+1 के मानों पर निर्भर करता है। कोड की 6 लाइनें 20 से बेहतर हैं। – Leonel

+0

मुझे इस समाधान को बहुत पसंद आया और अभ्यास को हल करने के लिए यह अजीब तरीका मिला: System.out.println ("Args:" + mainContext.getBean ("args")); \t \t स्ट्रिंग [] arg1 = (स्ट्रिंग []) ((संग्रह) mainContext.getBean ("args"))। ToArray (नया स्ट्रिंग [0]); \t \t स्ट्रिंग ओ = arg1 [0]; \t \t System.out.println (ओ); – hephestos

1

यहां एक मुख्य विधि के लिए पट्टा वसंत बूट करने का एक उदाहरण दिया गया है, बस पारित पैरा को सामान्य के रूप में पकड़ें, फिर उस फ़ंक्शन को जिसे आप अपने बीन पर कॉल करते हैं (मामले में 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; 
} 
+0

आह, मुझे यह उल्लेख करना चाहिए था कि कमांड लाइन को पार्स किए जाने के बाद मेरा वसंत प्रारंभिक अवश्य आना चाहिए, क्योंकि यह स्थिर संदर्भ के लिए कमांड लाइन – lowellk

5

आप getBean पर दूसरे पैरामीटर के रूप में ऑब्जेक्ट सरणी भी पास कर सकते हैं जिसका उपयोग कन्स्ट्रक्टर या फैक्ट्री के लिए तर्क के रूप में किया जाएगा। के साथ-साथ

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

} 

:

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

निम्नलिखित वर्ग पर विचार करें

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

} 
6

मेरी वसंत-CLI पुस्तकालय पर एक नजर डालें - http://github.com/sazzer/spring-cli पर - ऐसा करने का एक ही रास्ता के रूप में। यह आपको एक मुख्य श्रेणी देता है जो स्वचालित रूप से वसंत संदर्भों को लोड करता है और कमांड लाइन तर्कों को स्वचालित रूप से पार्स करने और उन्हें अपने सेम में इंजेक्शन देने के लिए कॉमन्स-सीएलआई का उपयोग करने की क्षमता रखता है।

4

वसंत 3.1 से शुरू करना अन्य उत्तरों में सुझाए गए किसी भी कस्टम कोड में कोई आवश्यकता नहीं है। CommandLinePropertySource देखें, यह आपके संदर्भ में सीएल तर्कों को इंजेक्ट करने का एक प्राकृतिक तरीका प्रदान करता है।

और आप अपने कोड एक कदम आगे तथ्य यह है कि SpringApplication आप निम्नलिखित देता है लाभ को आसान बनाने में कर सकता है यदि आप एक भाग्यशाली स्प्रिंग बूट डेवलपर हैं:

डिफ़ॉल्ट वर्ग द्वारा अपने आवेदन bootstrap करने के लिए निम्न चरणों का पालन करेंगे :

...

एक CommandLinePropertySource रजिस्टर आदेश पंक्ति तर्क बेनकाब करने के लिए स्प्रिंग गुण

के रूप में और अगर आप स्प्रिंग बूट संपत्ति संकल्प आदेश में रुचि रखते हैं this page से परामर्श लें।

संबंधित मुद्दे