Automatyczne okablowanie listy za pomocą schematu util daje NoSuchBeanDefinitionException

Mam fasolę, którą chcę wprowadzić z listą nazw używając przestrzeni nazw Spring util <util:list id="myList"> ale Spring szuka kolekcji fasolek typu String. Mój zepsuty test to:

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

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

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

Mój kontekst to:

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

Ale dostaję

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)

Co mnie bardziej zastanawia, ponieważ myślałem, że tak to będzie działać.

 87
Author: Paul McKenzie, 2009-09-01

3 answers

Wynika to z dość niejasnej części zachowania @ Autowired, określonej w 3.11.2. @ Autowired :

Możliwe jest również dostarczenie wszystkich fasola określonego rodzaju z ApplicationContext przez dodanie adnotacja do pola lub metody, które oczekuje tablicy tego typu...

To samo dotyczy zbiorów typowanych...

Innymi słowy, mówiąc @Autowired @Qualifier("myList") List<String>, prosisz o " podaj mi listę wszystkich fasoli typu java.lang.String, które mają kwalifikator "myList".

Rozwiązanie jest wymienione w 3.11.3. Autowirowanie na podstawie adnotacji z kwalifikatorami:

Jeśli zamierzasz wyrazić / align = "left" / , nie używaj przede wszystkim @Autowired - nawet jeżeli jest technicznie zdolny do odniesienia do nazwy fasoli przez @Qualifier wartości. Zamiast tego preferuj JSR-250 @Resource adnotacja, która jest semantycznie zdefiniowany w celu identyfikacji konkretny element docelowy według its unikalna nazwa, z deklarowany Typ brak znaczenia dla dopasowania proces.

jako szczególna konsekwencja tego różnica semantyczna, czyli siebie definiowane jako zbiór lub typ mapy nie może być wtryskiwany przez @Autowired ponieważ Dopasowanie typu nie jest odpowiednio do nich stosowane. użycie @Resource dla takiej fasoli, odnosząc się do konkretna kolekcja / Mapa unikalna nazwa.

Więc użyj tego w swoim teście, i działa dobrze:

@Resource(name="myList") private List<String> stringList;
 168
Author: skaffman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-31 14:08:50

Inną rzeczą, która może się dziać, jest to, że automatyzujesz własność fasoli. W takim przypadku nie trzeba go autowireować, ale wystarczy utworzyć metodę setter i użyć znacznika właściwości w definicji bean (przy użyciu xml) przykład:

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

I klasa:

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

Zobacz, Brak @Autowired adnotacji w klasie.

 0
Author: juliangonzalez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-11 22:57:03

Jeśli używałem JBoss 6.1, znalazłem adnotację @ Resource, która spowodowała, że moje wdrożenie nie powiodło się (szczegóły pominięte jako nieistotne dla pytania).

Ogólną alternatywą dla wszystkich serwerów aplikacji jest użycie adnotacji @ Inject (JSR-330).

 -1
Author: bazwilliams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-29 15:43:36