2011-01-11 13 views
15

विभिन्न चरणों के साथ एक चरणबद्ध अनुप्रयोग संदर्भ की कल्पना करो। हम आवश्यक बुनियादी ढांचे को परिभाषित करने के लिए शुरुआती चरण से शुरू करते हैं। एक्सएमएल अनुप्रयोग संदर्भ अनुक्रमिक रूप से लोड होते हैं।स्प्रिंग एप्लिकेशन संदर्भ में पहले से परिभाषित सूचियों और मानचित्रों का विस्तार कैसे करें?

इन फ़ाइलों को विभाजित करने का कारण एक एक्सटेंशन/प्लगइन तंत्र है।

स्टेज 01-default-configuration.xml

हम तैयार करने और आईडी exampleMapping के साथ नक्शा घोषित डेटा के साथ बाद में उन्हें बढ़ाने के लिए।

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:util="http://www.springframework.org/schema/util" 
     xsi:schemaLocation="[...]"> 

    <util:map id="exampleMapping" /> 
</beans> 

स्टेज 02-कस्टम configuration.xml(वैकल्पिक)

हम exampleMapping कॉन्फ़िगर और एक प्रवेश जोड़ें।

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:util="http://www.springframework.org/schema/util" 
     xsi:schemaLocation="[...]"> 

    <util:map id="exampleMapping"> 
    <entry key="theKey" value="theValue" /> 
    </util:map> 
</beans> 

स्टेज 03-मेक-उपयोग के- configuration.xml(अनिवार्य)

परिभाषित नक्शा exampleMapping का उपयोग करता है, चाहे वह customly कॉन्फ़िगर किया गया है या यह अभी भी खाली घोषित नक्शा है।

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="[...]"> 

    <bean id="exampleService" class="com.stackoverflow.example.ExampleService"> 
     <property name="mapping" ref="exampleMapping" /> 
    </bean> 
</beans> 

समस्या यहाँ है, यह है कि यह पहले चरण के बाद exampleMapping नक्शा करने के लिए प्रविष्टियों को जोड़ने के लिए संभव नहीं है। वसंत एक अपवाद फेंकता है कि आईडी exampleMapping वाला मानचित्र पहले से मौजूद है। यदि हम पहले चरण को छोड़ देते हैं तो नक्शा अव्यवस्थित है और तीसरा चरण exampleMapping को हल नहीं कर सकता है जो अपवाद भी उत्पन्न करता है।

मैं इस मुद्दे को कैसे हल कर सकता हूं? मैंने Collection merging (वसंत दस्तावेज़) पढ़ा लेकिन इससे मदद नहीं मिली। क्या इसका उपयोग करने से पहले नक्शे/सूचियों में मूल्यों को बाद में जोड़ना संभव है?

धन्यवाद!

+0

"पहले चरण के बाद प्रविष्टियों के साथ बढ़ाया नहीं जा सकता" से आपका क्या मतलब है? – skaffman

+0

@skaffman: क्षमा करें, ftfy। – codevour

उत्तर

10

आप exampleMapping परिभाषित कर सकते हैं दूसरी परिभाषा एक अलग फाइल में है, और आप <import resource="..."/> का उपयोग दूसरे में एक फ़ाइल आयात करने, लेकिन यह एक नाजुक दृष्टिकोण है, और आसानी से टूट।

मैं एक और मजबूत रणनीति का सुझाव देता हूं। एक Registry वर्ग, जो बारी में शामिल है और मैपिंग का प्रबंधन करता है साथ exampleMapping बदलें: फिर

public MappingRegistry<K,V> { 

    private final Map<K,V> mappings = new HashMap<K,V>(); 

    public void addMapping(K key, V value) { 
     mappings.put(key, value); 
    } 

    public Map<K,V> getMappings() { 
     return Collections.unmodifiableMap(mappings); 
    } 
} 

, एक वर्ग जो रजिस्ट्री के साथ एक मानचित्रण पंजीकृत करता लिखें:

public class MappingRegistrar<K,V> { 

    private final MappingRegistry<K,V> registry; 

    private K key; 
    private V value; 

    @Autowired 
    public MappingRegistrar(MappingRegistry<K,V> registry) { 
     this.registry = registry; 
    } 

    public void setKey(K key) { 
     this.key = key; 
    } 

    public void setValue(V value) { 
     this.value = value; 
    } 

    @PostConstruct 
    public void registerMapping() { 
     registry.addMapping(key, value); 
    } 
} 

अपने config की तरह कुछ हो जाता है इस:

<bean id="mappingRegistry" class="com.xyz.MappingRegistry"/> 

<bean id="mappingA" class="com.xyz.MappingRegistrar" p:key="keyA" p:value="valueA"/> 
<bean id="mappingB" class="com.xyz.MappingRegistrar" p:key="keyB" p:value="valueB"/> 
<bean id="mappingC" class="com.xyz.MappingRegistrar" p:key="keyC" p:value="valueC"/> 

ये मैपिंग अब किसी भी तरह से आप फिट देख में अपने config में फैले हुए किया जा सकता है, और वे स्वयं को इकट्ठा करेंगे। ExampleServcie को MappingRegistry के साथ इंजेक्शन दिया जाता है और तदनुसार मैपिंग निकालता है।

यह आपके पास पहले से मौजूद कुछ काम है, लेकिन यह बहुत अधिक लचीला और कम त्रुटि प्रवण है। यह विशेष रूप से मूल्यवान है यदि आप किसी प्रकार का एक विस्तारणीय ढांचा बनाने की कोशिश कर रहे हैं; आप लोगों को इसका उपयोग करने के तरीके पर कम बाधा डालना चाहते हैं।

+0

मैंने विशेष रूप से फ़िल्टर/मूल्य-प्रदाताओं के लिए एक एक्स्टेंसिबल सुविधा प्रदान करने के लिए पहले से ही इस तंत्र का उपयोग किया है। सोचा कि यह बहुत अधिक होगा और सूचियों/मानचित्रों के लिए इसे हासिल करने का एक आसान तरीका है। जाहिरा तौर पर नहीं। जैसा कि आपने प्रस्तावित किया है, मैं इसे लागू कर दूंगा। शायद हम भविष्य में ऐसी वसंत-सुविधा देखेंगे? धन्यवाद! – codevour

+0

@codevour: मुझे नहीं लगता कि यह अधिक है, मुझे लगता है कि यह एक अच्छा डिजाइन है। यह मेरी राय में, नग्न मानचित्र का उपयोग करने से अधिक मजबूत, अधिक स्पष्ट और अधिक पठनीय है। – skaffman

+1

आप सही हो सकते हैं, यह करने का यह एक बहुत ही सामान्य तरीका हो सकता है, सेम भी अज्ञात हो सकते हैं। इसके बारे में थोड़ा सोचा, यह मेरे दृष्टिकोण के लिए अच्छा फिट बैठता है। फिर से धन्यवाद। – codevour

13

map और list में यह विशेषता दो सूचियों को विलय करने के लिए merge=true|false नामांकित है। वैकल्पिक रूप से आप बाद में अतिरिक्त आइटम जोड़ने के लिए पहले से परिभाषित सूची की अतिरिक्त विधि को कॉल करने के लिए MethodInvokingFactoryBean का उपयोग कर सकते हैं।

चलो अपने उदाहरण पर जाएं।

1) MethodInvokingFactoryBean के साथ दूसरा दूसरा परिदृश्य। आपके द्वारा किए जाने वाले तरीके को परिभाषित करने के बजाय, मैंने आपके सेम को थोड़ा अलग तरीके से परिभाषित किया।

<bean class="java.util.HashMap" id="exampleMapping"> 
    <constructor-arg index="0"> 
     <map> 
      <entry key="theKey" value="theValue"/> 
     </map> 
    </constructor-arg> 
</bean> 

<bean id="exampleService" class="com.stackoverflow.example.ExampleService"> 
    <property name="mapping" ref="exampleMapping"/> 
</bean> 

किसी अन्य एप्लिकेशन सामग्री फ़ाइल में, आप मानचित्र का विस्तार करने के लिए निम्नलिखित कार्य कर सकते हैं।

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="targetObject" ref="exampleMapping"/> 
    <property name="targetMethod" value="putAll"/> 
    <property name="arguments"> 
     <list> 
      <map id="exampleMapping"> 
      <entry key="theKey2" value="theValue2"/> 
      <entry key="theKey3" value="theValue3"/> 
      <map> 
     </list> 
    </property> 
</bean> 

2) अब पहला परिदृश्य। इस एक के लिए, मैं सिर्फ पेज http://forum.springsource.org/showthread.php?t=53358

<bean id="commonData" class="A"> 
    <property name="map"> 
     <util:map> 
      <entry key="1" value="1"/> 
     </util:map> 
    </property> 
</bean> 
<bean id="data" class="A" parent="commonData"> 
    <property name="map"> 
     <util:map merge="true"> 
      <entry key="2" value="2"/> 
     </util:map> 
    </property> 
</bean> 

आशा है कि यह मदद करता है पर कुछ पाया।

+0

क्या आप एक साधारण उदाहरण प्रदान कर सकते हैं? दुर्भाग्य से मुझे यह नहीं चल रहा है। – codevour

+0

मैंने जवाब अपडेट किया और दोनों विकल्पों के लिए एक उदाहरण दिया। –

+0

मुझे लगता है कि पहला परिदृश्य इस दृष्टिकोण के लिए एक महान डिजाइन नहीं है और मुझे बहुत गंदे लगता है। दूसरा एक थोड़ा अपमानजनक है, मुझे लगता है कि स्काफमैन के रूप में एक रजिस्ट्री लिखना सबसे अच्छा होगा। आपके उत्तर और स्पष्टीकरण के लिए धन्यवाद! – codevour

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