manejo - jlist java eclipse
El auto-cableado de una lista usando el esquema util da NoSuchBeanDefinitionException (3)
Esto se debe a una parte bastante oscura del comportamiento de @ Autowired, especificado en 3.11.2. @Autowired :
También es posible proporcionar todos los beans de un tipo particular desde
ApplicationContext
agregando la anotación a un campo o método que espera una matriz de ese tipo ...Lo mismo aplica para colecciones escritas ...
En otras palabras, al decir @Autowired @Qualifier("myList") List<String>
, en realidad está pidiendo "darme la lista de todos los beans de tipo java.lang.String
que tienen el calificador" myList ".
La solución se menciona en 3.11.3. Ajuste el autoenlace basado en anotaciones con calificadores :
Si tiene la intención de expresar una inyección controlada por anotación por su nombre, no use principalmente
@Autowired
, incluso si es técnicamente capaz de hacer referencia a un nombre de bean a través de los valores de@Qualifier
. En su lugar, prefiera la anotación JSR-250@Resource
que se define semánticamente para identificar un componente objetivo específico por su nombre único, con el tipo declarado como irrelevante para el proceso de coincidencia.Como consecuencia específica de esta diferencia semántica, los beans que se definen a sí mismos como un tipo de colección o mapa no se pueden inyectar a través de
@Autowired
ya que la coincidencia de tipos no se aplica correctamente a ellos. Use@Resource
para dichos beans, haciendo referencia al bean de colección / mapa específico por nombre único.
Entonces use esto en su prueba, y funciona bien:
@Resource(name="myList") private List<String> stringList;
Tengo un bean que quiero inyectar con una lista con nombre utilizando Spring namespace <util:list id="myList">
pero Spring está buscando una colección de beans de tipo String. Mi prueba rota es:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ListInjectionTest {
@Autowired @Qualifier("myList") private List<String> stringList;
@Test public void testNotNull() {
TestCase.assertNotNull("stringList not null", stringList);
}
}
Mi contexto es:
<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>
Pero yo obtengo
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)
Lo que me desconcierta más bien es que pensé que esta sería la forma en que se esperaba que funcionara.
Otra cosa que podría estar sucediendo es que estás conectando automáticamente una propiedad de un frijol. En tal caso, no es necesario que se autoenlace, simplemente cree el método setter y use la etiqueta de propiedad en la definición de bean (cuando se usa xml) ejemplo:
<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>
Y la clase:
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;
}
Mira, no @Autowired
Anotación @Autowired
en clase.
Si utilizo JBoss 6.1, encontré que la anotación @Resource hizo que fallara mi implementación (detalle omitido como irrelevante para la pregunta).
Una alternativa general para todos los servidores de aplicaciones es usar la anotación @Inject ( JSR-330 ).