2011-10-14 11 views
41

जब मैंने पहली बार स्प्रिंग के बारे में सीखना शुरू किया, तो अनुप्रयोग को कॉन्टेक्स्ट.एक्सएमएल फ़ाइल में कॉन्फ़िगर किया गया था। तब जब मैंने विशेष रूप से वसंत के हाल के संस्करणों पर किताबें पढ़ना शुरू किया, तो उन्होंने सभी अलग-अलग एक्सएमएल फाइलों जैसे कॉन्फ़िगरेशन को myapp-servlet-xml, myapp-security.xml, myapp-service.xml, आदि में किया है। web.xml फ़ाइल में संदर्भ कॉन्फ़िगर स्थान कॉन्फ़िगर करें। तो, उदाहरण के लिए, कोड मैं के साथ निम्न किया गया है इस लिए किया था के रूप में यह contextConfigLocation है:स्प्रिंग एक्सएमएल फ़ाइल कॉन्फ़िगरेशन पदानुक्रम सहायता/स्पष्टीकरण

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     /WEB-INF/myapp-servlet.xml 
     /WEB-INF/myapp-data.xml 
    </param-value> 
</context-param> 

वैसे भी, हाल ही में मैं एक कॉन्फ़िगरेशन समस्या (जो यहाँ StackOverflow पर उपयोगी लोगों ने मुझे यह पता लगाने में मदद मिली) में भाग कि इस अलगाव के कारण था। इन पुस्तकों के उदाहरणों के लिए कोई applicationContext.xml फ़ाइल नहीं थी और बाद में जब मैंने ऐप में स्वत: स्कैनिंग और एनोटेशन जोड़ने की कोशिश की तो इससे समस्याएं आईं। मैंने सबकुछ applicationContext.xml में ले जाने की कोशिश की और अन्य फाइलों से दूर कर दिया और समस्या को हल किया। कुछ भी नहीं बदला, मैं बस सबकुछ ApplicationContext.xml में डाल दिया।

तो, यह, दूसरों से टिप्पणी के साथ, मुझे करने के लिए नेतृत्व किया है एक तरह से समझते हैं कि भले ही आप एक applicationContext.xml नहीं बनाते हैं, यह अभी भी प्रयोग किया जा रहा है और यह विन्यास पदानुक्रम के कुछ प्रकार के शीर्ष स्तर है । मुझे आशा है कि कोई और मुझे समझा सकता है कि यह सब कैसे काम करता है क्योंकि मैं कहीं भी किसी भी स्पष्टीकरण में नहीं आया हूं।

तो उदाहरण के लिए, यदि मैं कुछ संदर्भ डालता हूं: कॉन्फ़िगरेशन फ़ाइलों में घटक-स्कैन टैग जो अनुप्रयोग Context.xml से नीचे हैं, तो इससे कुछ वर्ग स्कैन नहीं हो सकते हैं। उस प्रकृति की चीजें। मैं प्राथमिकता को समझ नहीं पा रहा हूं और यह सुनिश्चित करना है कि यह सुनिश्चित किया जाए कि यह एप्लिकेशन व्यापक रूप से देखा गया है और इसी तरह। अगर कोई इसे स्पष्ट रूप से समझा सकता है या मुझे उस संसाधन को इंगित कर सकता है जो इसे समझाता है तो मैं इसकी सराहना करता हूं, धन्यवाद। उम्मीद है कि मैं जो पूछ रहा हूं वह समझ में आता है।

उत्तर

83

"applicationContext.xml" नाम की फ़ाइल के बारे में कुछ खास नहीं है, सिवाय इसके कि इसका नाम स्प्रिंग इसकी डिफ़ॉल्ट कॉन्फ़िगरेशन फ़ाइल के रूप में अपेक्षा करता है। "Dog.xml" नामक एक फ़ाइल का उपयोग करके, "cat.xml", और "alien.xml" ठीक उसी तरह काम करेगा। आपके पास जो समस्या हो रही है, वह एक ही समय में एकाधिक अनुप्रयोग कॉन्टैक्स का उपयोग करने से आता है, न कि एकाधिक एक्सएमएल फाइलों से। मैंने हाल ही में उन लोगों से कुछ प्रश्नों का उत्तर दिया है जिनके पास इन अवधारणाओं को समझने के कारण समस्याएं थीं। उन के उत्तर देते हैं, और देखो क्या सवाल आप अभी भी है:

Declaring Spring Bean in Parent Context vs Child Context

Spring-MVC: What are a "context" and "namespace"?

संपादित करें: अपने नए प्रश्न के उत्तर में:

मैं में एक <context:component-scan base-package="com.myapp"/> टैग था मेरी servlet.xml।

मैं इस "servlet.xml" फ़ाइल अनुमान लगा रहा हूँ की तरह

<servlet> 
    <servlet-name>foo</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
</servlet> 

परंपरा के मुताबिक, जब यह, foo-servlet.xml, जहां DispatcherServlet अपने web.xml में विन्यस्त "foo" नाम दिया गया है की तरह नाम है डिस्पैचर सर्वलेट शुरू होता है, यह एक नया एप्लीकेशन कॉन्टेक्स्ट बनाएगा जो फ़ाइल foo-servlet.xml द्वारा कॉन्फ़िगर किया गया है, जो servlet-name से लिया गया है। अब, चूंकि आपने वहां context:component-scan डाला है, इसलिए यह दिए गए पैकेज को फिर से स्कैन करने और सभी एनोटेटेड कक्षाओं के लिए बीन्स बनाने जा रहा है।आपके द्वारा दिया गया पैकेज, com.myapp, ऐसा लगता है कि यह आपके पूरे ऐप के लिए बेस पैकेज है, इसलिए वसंत से से आपके ऐप में एनोटेटेड क्लास के सभी से डेटा एक्सेस सहित, इस एप्लिकेशन कॉन्टेक्स्ट में शामिल होगा DispatcherServlet। आम तौर पर, इस संदर्भ में केवल दृश्य-परत सामग्री और सेम होना चाहिए जो सीधे इसमें डिस्पैचर सर्वलेट का समर्थन करते हैं, इसलिए यह गलत कॉन्फ़िगरेशन का था।

मेरी डेटा.एक्सएमएल फ़ाइल में मेरे पास डेटा स्रोत बीन्स था और वह था। कोई अन्य सेम नहीं, बाकी सब कुछ स्वचालित और एनोटेट किया गया था।

मुमकिन है, यह "data.xml" फ़ाइल एक आप contextConfigLocation संदर्भ परम में सूचीबद्ध है। आप भी यह मानते हुए कि आपके द्वारा web.xml को ContextLoaderListener कहा,

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

फिर उस फ़ाइल को एक दूसरे ApplicationContext बनाने के लिए इस्तेमाल किया जाएगा की तरह - जड़ संदर्भ। यही श्रोता यह करता है। ध्यान दें कि यह वास्तव में contextConfigLocation में सूचीबद्ध फ़ाइलों से संदर्भ बनाता है, और यदि आपने उस सूची में अपना "servlet.xml" भी शामिल किया है, तो आपने उस कॉन्फ़िगर को दो बार लोड किया है: यहां मूल संदर्भ के साथ-साथ DipatcherServlet से जुड़े संदर्भ। उम्मीद है कि अब आप देखते हैं कि XML कॉन्फ़िगरेशन फ़ाइलों और उनके द्वारा कॉन्फ़िगर किए गए एप्लिकेशन कॉन्टेक्सट्स के बीच एक अलग विभाजन कैसे होता है। दो अलग-अलग संदर्भों को कॉन्फ़िगर करने के लिए एक ही एक्सएमएल फ़ाइल का आसानी से उपयोग किया जा सकता है। चाहे ऐसा करना सही है या नहीं, एक और सवाल है। इस विशेष मामले में, यह नहीं है।

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

मैंने फिर अपनी सेवा बीन में @ ट्रांस्केनेशन जोड़ने की कोशिश की और यह जारी नहीं रहेगा।

काम करने के लिए @Transactional, आप ApplicationContext जहां सेम जीवन एनोटेट के विन्यास में <tx:annotation-driven/> टैग शामिल होना आवश्यक के लिए आदेश में। यह चाल "जहां यह रहता है" भाग का पता लगा रही है। एक बच्चे में बीन्स एक मूल संदर्भ में सेम ओवरराइड कर सकते हैं। इसलिए - मैं बस अनुमान लगा रहा हूं - अगर आपने उपरोक्त वर्णित अनुसार अपने सभी बीन्स को डिस्पैचर सर्वलेट संदर्भ में लोड किया है, लेकिन रूट संदर्भ में <tx:annotation-driven/> डालें, तो आपके पास रूट संदर्भ में एक बीन हो सकता है जो सही ढंग से लेनदेन वाला है, लेकिन यह नहीं है इसका इस्तेमाल किया जा रहा है क्योंकि नकल माता-पिता/बाल पदानुक्रम में सर्वलेट के लिए "करीब" है, और जिस संदर्भ में इसे <tx:annotation-driven/> कॉन्फ़िगरेशन नहीं मिला है।

जब मैंने सर्वलेट संदर्भ बदल दिया: घटक-स्कैन टैग इसके बजाय com.myapp.web पर इंगित करें और फिर एक संदर्भ जोड़ा: data.xml फ़ाइल में घटक-स्कैन टैग, सबकुछ काम करता है।

यह अभी भी आप सहित किये गए जिसमें ApplicationContexts है, लेकिन बहुत कम से कम मैं कह सकता हूँ कि ऐसा करके, आप जो भी समस्या खड़ी कर रहे थे DispatcherServlet के संदर्भ से सेम का एक बहुत हटा दिया वास्तव में कौन-config फ़ाइलों पर कुछ हद तक निर्भर करता है। विशेष रूप से, रूट संदर्भ में आपके सही ढंग से कॉन्फ़िगर किए गए @ ट्रान्सैक्शनल बीन्स अब बच्चे के संदर्भ में बीन्स द्वारा छायांकित नहीं होंगे और आपके नियंत्रकों में इंजेक्शन दिए जाएंगे, इसलिए आपकी दृढ़ता सामग्री तब काम करेगी।

तो ... मुख्य बात यह है कि आपके पास दो संबंधित एप्लिकेशन कॉन्टेक्स हैं। आपको उस तथ्य के प्रति जागरूक रहना होगा और उस पर नियंत्रण रखना होगा कि कौन से सेम संदर्भ में जाते हैं।

क्या इसमें सबकुछ शामिल है?

+0

सहायता और लिंक के लिए बहुत बहुत धन्यवाद। लिंक मैंने कुछ स्पष्टीकरण प्रदान किए जिन्हें मैं ढूंढ रहा था। हालांकि, मेरे पास भी प्रश्न हैं। मेरे पास टैग my servlet.xml में था। मेरी data.xml फ़ाइल में मेरे पास डेटा स्रोत बीन्स था और वह था। कोई अन्य सेम नहीं, बाकी सब कुछ स्वचालित और एनोटेट किया गया था। मैंने फिर अपनी सेवा बीन में @ ट्रान्ससेनलिंग जोड़ने की कोशिश की और यह जारी नहीं रहेगा। जब मैंने सर्वलेट संदर्भ बदल दिया: घटक-स्कैन टैग को com.myapp.web पर इंगित करने के लिए और फिर एक संदर्भ जोड़ा: data.xml फ़ाइल में घटक-स्कैन टैग, सब कुछ काम किया। – cardician

+0

तो मेरा सवाल होगा, क्या आप स्पष्ट कर सकते हैं कि ऐसा क्यों है? मेरे पास एक प्रेषक सर्वलेट है जो servlet.xml को देखता है ताकि रूट संदर्भ न हो। हमम ... मुझे लगता है कि मैं अभी भी पूरी तरह से समझ नहीं पा रहा हूं कि चीजें कैसे फिट होती हैं। हालांकि बहुत बहुत धन्यवाद। – cardician

+0

आपके लिए जबरदस्त धन्यवाद! मुझे लगता है कि आपने वास्तव में उन पुस्तकों और स्प्रिंग डॉक्स से जो कुछ भी पढ़ा है, उससे मुझे लगता है कि मैं जो स्पष्ट नहीं कर पाया था उसे साफ़ करने में मदद की है। मैं वास्तव में संदर्भ में मेरी serlvet.xml फ़ाइल डाल रहा था कॉन्फिग स्थान सूची जो आपने कहा था 2 संदर्भों का कारण बन रहा था। शायद यह मेरी एकमात्र समस्या नहीं थी लेकिन निश्चित रूप से उनमें से एक थी। अब आपके स्पष्टीकरण के साथ मुझे यह सुनिश्चित करने में सक्षम होना चाहिए कि सब ठीक से कॉन्फ़िगर किया गया है। इसके अलावा मैं आपको यह भी सराहना करता हूं कि स्प्रिंग फाइलों को कैसे लोड करता है। मुझे लगता है कि सब कुछ ज्यादा स्पष्ट है। एक बार फिर धन्यवाद। – cardician

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