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ć.
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;
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.
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).
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