2010-07-29 6 views
20

Tengo lo que parece ser un problema simple, como se indica en el título. Aquí es el tipo de clase que tengo:Autocableando una colección a través del constructor con Spring

public class Foo { 
    @Autowired 
    public Foo(@Qualifier("bar") Set<String> bar) { 
     // ... 
    } 
} 

que trato de correr con el siguiente contexto de primavera:

<context:annotation-config /> 
<util:set id="bar"> 
    <value>tata</value> 
    <value>titi</value> 
    <value>toto</value> 
</util:set> 
<bean id="foo" class="Foo" /> 

Esto no se puede ejecutar con:

Sin coincidente frijol de tipo [java.lang.String] encontrado para dependencia [colección de java.lang.String]: se espera al menos 1 bean que califica como autowire candidato para esta dependencia. anotaciones Dependencia: {@ org.springframework.beans.factory.annotation.Qualifier (valor = bar)}

Tenga en cuenta que si añado otros parámetros a mi constructor, que trabaja muy bien. Si uso setter injection, funciona bien. Estoy seguro de que echo de menos algo obvio ... ¿sabes qué?

Respuesta

22

colecciones Autowiring no es posible utilizando la anotación @Autowired. Una colección autocableada significa "proporcionar todos los granos de un tipo particular". Usando la anotación JSR-250 @Resource, puede declarar que desea que un recurso sea inyectado por su nombre, no por su tipo. O inyecta la dependencia de forma explícita.

[...] judías que a su vez se definen como una colección o escribe el mapa puede no ser inyectado a través de @Autowired ya que el tipo de adaptación no es propiamente aplicable a ellos. Use @Resource para dichos beans, haciendo referencia al bean de colección/mapa específico por nombre único.

Ver the Spring documentation para más detalles.

2

I que esto se debe a la primavera interpreta el autowiring de una colección como "dame todos los granos de tipo String", en lugar de "dame el frijol, que es una colección de String". El mensaje de error apoya esa idea.

No creo que pueda utilizar el autoenvío para esto. A falta de cableado manualmente hacia arriba en el XML, lo mejor que puedo sugerir es:

public class Foo { 
    private @Resource Set<String> bar; 
} 
5

Como han dicho otros, es imposible utilizar @Autowired para cadenas y colecciones de String. Se puede utilizar con la primavera @Valor EL aquí suponiendo que tiene la primavera en la versión 3:

 
public class Foo { 
    @Autowired 
    public Foo(@Value("#{bar}") Set<String> bar) { 
     // ... 
    } 
} 
2

tenía este mismo problema y se inspiró en @rembisz's answer. Esa respuesta no funcionó en mi versión de Spring (4.1.3). Cuando revisé el SpEL documentation on bean references, encontré una sintaxis de SpEL diferente para expresar las referencias de bean en los valores de autoenlace que me funcionaron: @beanname. Como tal, el siguiente código funcionó para mí:

public class Foo { 
    @Autowired 
    public Foo(@Value("#{@bar}") Set<String> bar) { 
     // ... 
    } 
} 
Cuestiones relacionadas