ऑटो-वायरिंग लिस्ट इन यूज़िंग स्कीमा का उपयोग करके NoSuchBeanDefinitionException देता है


90

मेरे पास एक बीन है जिसे मैं स्प्रिंग यूज़ नेमस्पेस का उपयोग करके एक नामित सूची के साथ इंजेक्ट करना चाहता हूं <util:list id="myList">लेकिन वसंत इसके बजाय टाइप स्ट्रिंग के बीन्स के संग्रह की तलाश कर रहा है। मेरी टूटी हुई परीक्षा है:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ListInjectionTest {

    @Autowired @Qualifier("myList") private List<String> stringList;

    @Test public void testNotNull() {
        TestCase.assertNotNull("stringList not null", stringList);
    }
}

मेरा संदर्भ है:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:util="http://www.springframework.org/schema/util"
   xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

   <util:list id="myList">
       <value>foo</value>
       <value>bar</value>
   </util:list>

</beans>

लेकिन मुझे मिलता है

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [collection of java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myList)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:726)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:571)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:412)

जो मुझे लगता है कि पहेली के रूप में मैं यह काम करने की उम्मीद थी जिस तरह से होगा।

जवाबों:


171

यह 3.11.2 में निर्दिष्ट @ Autowired के व्यवहार के बजाय अस्पष्ट भाग के कारण है @ स्वचालित :

किसी विशेष प्रकार की सभी फलियों ApplicationContextको किसी क्षेत्र या विधि में एनोटेशन जोड़कर प्रदान करना संभव है जो उस प्रकार की एक सरणी की अपेक्षा करता है ...

टाइप किए गए संग्रह के लिए भी यही लागू होता है ...

दूसरे शब्दों में, कहकर @Autowired @Qualifier("myList") List<String>, आप वास्तव में "मुझे सभी प्रकार की फलियों की सूची प्रदान करने के लिए कह रहे हैं, java.lang.Stringजिनके पास" माईलिस्ट "क्वालिफायर है।

3.11.3 में समाधान का उल्लेख है क्वालिफ़ायर के साथ फाइन-ट्यूनिंग एनोटेशन-आधारित ऑटोवेयरिंग :

यदि आप नाम से एनोटेशन-संचालित इंजेक्शन व्यक्त करने का इरादा रखते हैं, तो प्राथमिक रूप से उपयोग न करें @Autowired- भले ही तकनीकी रूप से @Qualifier मूल्यों के माध्यम से एक बीन नाम का उल्लेख करने में सक्षम हो । इसके बजाय, JSR-250 @Resource एनोटेशन को प्राथमिकता दें, जो कि मिलान प्रक्रिया के लिए अप्रासंगिक होने के साथ अपने विशिष्ट नाम से एक विशिष्ट लक्ष्य घटक की पहचान करने के लिए शब्दार्थ से परिभाषित किया गया है।

इस शब्दार्थिक अंतर के एक विशिष्ट परिणाम के रूप में, बीन्स जो खुद को एक संग्रह या मानचित्र प्रकार के रूप में परिभाषित करते हैं, के माध्यम @Autowiredसे इंजेक्ट नहीं किया जा सकता क्योंकि टाइप मिलान उनके लिए ठीक से लागू नहीं है। @Resourceविशिष्ट नाम / विशिष्ट बीन द्वारा अद्वितीय नाम का उल्लेख करते हुए ऐसी फलियों का उपयोग करें ।

तो अपने परीक्षण में इसका उपयोग करें, और यह ठीक काम करता है:

@Resource(name="myList") private List<String> stringList;

9
आप एक जीवन सुरक्षित हैं और इसलिए stackoverflow.com है! :)
रिहर्सल २ '

5
अगर मैं कर सकता तो मैं यह दस वोट देता। आप दा मैन, स्केफमैन हैं।
duffymo

3
इस तथ्य से कई भ्रमित हो गए हैं, इसका अर्थ यह है कि शब्दार्थ वास्तव में भ्रमित करने वाला है। मुझे आश्चर्य है कि इस तरह के भ्रामक डिजाइन के पीछे कारण क्या था।
सुपरटनस्की

3
वाह, मैं वसंत को प्रोग्रामिंग में अपने सबसे मजबूत क्षेत्रों में से एक मानता हूं और मैंने आज तक इस मुद्दे का कभी सामना नहीं किया और आपने मुझे बहुत समय दिया। धन्यवाद!
एवी

2
निर्माणकर्ता / विधि इंजेक्शन के साथ काम करने के तरीके के बारे में कोई सुझाव, @Resource पैरामीटर का समर्थन नहीं करता है?
cjbooms

0

एक और बात जो हो सकती है वह यह है कि आप एक सेम की संपत्ति को स्वायत्त कर रहे हैं। ऐसे मामले में आपको इसे स्वायत्त करने की आवश्यकता नहीं है, लेकिन बस सेटर विधि बनाएं और बीन परिभाषा में संपत्ति टैग का उपयोग करें (जब xml का उपयोग करके) उदाहरण:

<bean id="cleaningUpOldFilesTasklet" class="com.example.mypackage.batch.tasklets.CleanUpOldFilesTasklet">
    <property name="directoriesToClean">
        <list>
            <value>asfs</value>
            <value>fvdvd</value>
            <value>sdfsfcc</value>
            <value>eeerer</value>
            <value>rerrer</value>
        </list>
    </property>
</bean>

और वर्ग:

public class CleanUpOldFilesTasklet extends TransferingFilesTasklet implements Tasklet{

private long pastMillisForExpiration;
private final String dateFormat = "MM.dd";
Date currentDate = null;

List<String> directoriesToClean;

public void setDirectoriesToClean(List<String> directories){
    List<String> dirs = new ArrayList<>();
    for(String directory : directories){
        dirs.add(getSanitizedDir(directory));
    }
    this.directoriesToClean = dirs;
}

देखें, @Autowiredकक्षा में कोई टिप्पणी नहीं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.