2012-12-10 19 views
31

के साथ संघर्ष करता है मुझे कुछ वसंत बीन परिभाषाओं में समस्या है। मेरे पास कुछ संदर्भ xml फ़ाइलें हैं जो मेरी मुख्य() विधि द्वारा लोड की जा रही हैं, और उनमें से दोनों में लगभग एक टैग शामिल है। मेरी मुख्य विधि शुरू होता है, मैं वसंत से इस त्रुटि मिलती है:एनोटेशन-निर्दिष्ट बीन नाम मौजूदा, गैर-संगत बीन डीफ़

@Repository("converterDAO") 
public class StaticConverterDAOImpl implements ConverterDAO { 
... 
} 

इन-स्मृति दाव भी @Repository ("converterDAO" है:

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'converterDAO' for bean class [my.package.InMemoryConverterDaoImpl] conflicts with existing, non-compatible bean definition of same name and class [my.other.package.StaticConverterDAOImpl] 

दोनों डीएओ कक्षाएं इस तरह से एनोटेट) एनोटेशन। दाव इस तरह अन्य वर्गों में संदर्भित है:

... 
private @Autowired @Qualifier("converterDAO") ConverterDAO converterDAO; 
... 

मैं एक डीएओ चाहते एक दूसरे की परिभाषा है, जो जैसा कि मैं हमेशा से समझ में आ यह प्रमुख कारण पहले में एक डि ढांचे का उपयोग करने के लिए में से एक था ओवरराइड करने के लिए जगह। मैं वर्षों से एक्सएमएल परिभाषाओं के साथ ऐसा कर रहा हूं और कभी भी कोई समस्या नहीं थी। लेकिन घटक स्कैन और एनोटेटेड बीन परिभाषाओं के साथ ऐसा नहीं है? और वसंत का क्या मतलब है जब यह कहता है कि वे "संगत" नहीं हैं? वे एक ही इंटरफ़ेस को लागू है, और वे फ़ील्ड्स कि इंटरफ़ेस प्रकार के होते हैं में autowired कर रहे हैं। वे बिल्ली क्यों संगत नहीं हैं?

क्या कोई मुझे एक एनोटेटेड, घटक-स्कैन किए गए बीन के लिए किसी अन्य को ओवरराइड करने का तरीका प्रदान कर सकता है?

-माइक

+0

आपके साथ दूसरे कोड स्निपेन के साथ कुछ मजाकिया है ... कृपया इसे जांचें। – Yevgeniy

+0

शायद आपको अपनी मुख्य विधि साझा करने की आवश्यकता है? –

+0

कृपया कनवर्टर डीडीओ क्षेत्र की वास्तविक घोषणा जोड़ें। क्या यह 'कनवर्टरडाओ' इंटरफ़ेस या कार्यान्वयन है - यह प्रश्न से स्पष्ट नहीं है। –

उत्तर

22

एक XML फ़ाइल में, वहाँ घोषणाओं के एक दृश्य है, और आप को किसी नए के साथ पिछले एक परिभाषा भी पार कर जाते। जब आप एनोटेशन का उपयोग करते हैं, तो के बाद या से पहले की कोई धारणा नहीं है। सभी सेम एक ही स्तर पर हैं। आपने दो बीन्स को एक ही नाम से परिभाषित किया है, और वसंत को यह नहीं पता कि इसे कौन सा चुनना चाहिए।

उन्हें एक अलग नाम (staticConverterDAO, उदाहरण के लिए inMemoryConverterDAO), स्प्रिंग एक्सएमएल फ़ाइल (उदाहरण के लिए theConverterDAO) में एक उपनाम बनाएं दें, और जब कनवर्टर इंजेक्शन लगाने के इस अन्य नाम का उपयोग:

@Autowired @Qualifier("theConverterDAO") 
+1

पहले या बाद में कोई विचार क्यों नहीं है? मेरे पास दो संदर्भ फाइलें हैं, एक लोड हो गया है, फिर अगला। उस संबंध में शुद्ध एक्सएमएल परिभाषाओं से अलग नहीं होता है। ऑर्डर केवल वह क्रम है जिसके द्वारा घटक-स्कैन निर्देश सामने आते हैं। पहले स्कैन द्वारा उत्पादित दूसरे स्कैन ओवरराइड सेम द्वारा उत्पादित बीन्स। मैं सुनता हूं कि आप क्या कह रहे हैं, लेकिन मुझे इसके पीछे तर्क या तकनीकी कारण समझ में नहीं आता है। इसके अलावा यह दस्तावेज नहीं है और अपवाद बिल्कुल समझ में नहीं आता है। पाठ्यक्रम की आपकी गलती नहीं :-) उपनाम विचार के लिए अंक। एक्सएमएल परिभाषाओं पर वापस जाने से बेहतर। – user1283068

+0

इसके अलावा, सुझाव के संबंध में, यह निहितार्थ है कि कनवर्टरडाओ के सभी अलग-अलग कार्यान्वयन का पता लगाया जाएगा और संदर्भ फ़ाइलों को लोड होने पर वसंत द्वारा तत्काल कार्यान्वित किया जाएगा। एक्सएमएल के साथ, केवल अंतिम ओवरराइडिंग कार्यान्वयन ही किया जाएगा। इसका मतलब है कि सभी कनवर्टर डीओ कार्यान्वयन की सभी स्वाभाविक निर्भरताएं मौजूद हैं, भले ही केवल एक का उपयोग किया जाएगा। – user1283068

+0

जार अभिलेखागार के साथ बीन नाम संघर्ष से बचने के लिए कोई रणनीति? – Stephane

19

मैं एक परियोजना में दो जार पुस्तकालयों (APP1 और APP2) के साथ एक समान समस्या थी,। बीन "बीननाम" को एप 1 में परिभाषित किया गया है और इसे एप 2 में बढ़ाया गया है और उसी नाम से बीन को फिर से परिभाषित किया गया है।

APP1 में:

package com.foo.app1.pkg1; 

@Component("BeanName") 
public class Class1 { ... } 

APP2 में:

package com.foo.app2.pkg2; 

@Component("BeanName") 
public class Class2 extends Class1 { ... } 

यह वही घटक सेम नाम की वजह से applicationContext की लोडिंग में ConflictingBeanDefinitionException अपवाद का कारण बनता है।

इस समस्या को हल करने के लिए, स्प्रिंग विन्यास फाइल applicationContext.xml में:

<context:component-scan base-package="com.foo.app2.pkg2"/> 
<context:component-scan base-package="com.foo.app1.pkg1"> 
    <context:exclude-filter type="assignable" expression="com.foo.app1.pkg1.Class1"/> 
</context:component-scan> 

तो Class1 नाम संघर्ष से बचने, स्वचालित रूप से घटक-स्कैन और एक सेम करने के लिए आवंटित होने के लिए बाहर रखा गया है।

12

मैं @RestController का उपयोग कर स्प्रिंग 4.x के साथ एक समान मुद्दा था।दो अलग अलग संकुल में एक ही नाम के साथ एक कक्षा ...

package com.x.catalog 

@RestController 
public class TextureController { 
... 

package com.x.cms 
@RestController 
public class TextureController { 
... 

ठीक आसान था ...

package com.x.catalog 

@RestController("CatalogTextureController") 
public class TextureController { 
... 

package com.x.cms 
@RestController("CMSTextureController") 
public class TextureController { 
... 

समस्या हो कि एनोटेशन autowired और द्वारा वर्ग के नाम लेता हो जाता है लगता है था चूक। @RestController एनोटेशन में इसे एक स्पष्ट नाम देने से आप कक्षा के नामों को रखने की अनुमति देते हैं।

+1

धन्यवाद, आकर्षण की तरह काम किया। – Azim