Guía Completa: Spring - Injecting Collection
Introducción
En Spring Framework, la inyección de colecciones es una característica que permite inyectar múltiples valores en un solo bean. Esta característica es útil cuando se necesitan agrupar varios objetos relacionados en una colección (como una lista, conjunto o mapa) y luego pasarlos a un componente o clase dentro de la aplicación de Spring. La inyección de colecciones es parte del proceso de Inyección de Dependencias (DI) de Spring, y se puede realizar de varias maneras, como por ejemplo a través de la configuración en archivos XML o mediante anotaciones.
A continuación, se explicará cómo inyectar colecciones en beans usando Spring y algunos ejemplos para clarificar los conceptos.
Tipos de Colecciones en Spring
Spring puede inyectar las siguientes colecciones en los beans:
- Listas (
List
): Mantienen el orden de los elementos y permiten elementos duplicados. - Conjuntos (
Set
): No mantienen el orden de los elementos y no permiten elementos duplicados. - Mapas (
Map
): Permiten almacenar pares clave-valor.
1. Inyección de Colecciones en Spring
1.1 Inyección de Colección a través de XML
Una forma común de inyectar colecciones en Spring es mediante el archivo de configuración XML. A continuación, se muestra un ejemplo de cómo inyectar una lista de elementos.
Archivo beans.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Definición del bean que contiene la colección -->
<bean id="myCollectionBean" class="com.ejemplo.MyCollectionBean">
<property name="items">
<list>
<value>Elemento 1</value>
<value>Elemento 2</value>
<value>Elemento 3</value>
</list>
</property>
</bean>
</beans>
Clase Java:
package com.ejemplo;
import java.util.List;
public class MyCollectionBean {
private List<String> items;
public void setItems(List<String> items) {
this.items = items;
}
public void mostrarItems() {
for (String item : items) {
System.out.println(item);
}
}
}
1.2 Inyección de Colección a través de Anotaciones
Otra forma de inyectar colecciones es utilizando anotaciones como @Autowired
en lugar de XML. Esto se utiliza principalmente con componentes Spring que están definidos con anotaciones como @Component
, @Service
, etc.
Clase Java con @Autowired
:
package com.ejemplo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class MyCollectionBean {
private List<String> items;
@Autowired
public void setItems(List<String> items) {
this.items = items;
}
public void mostrarItems() {
for (String item : items) {
System.out.println(item);
}
}
}
Clase de Configuración:
package com.ejemplo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import java.util.Arrays;
import java.util.List;
@Configuration
@ComponentScan(basePackages = "com.ejemplo")
public class AppConfig {
@Bean
public List<String> items() {
return Arrays.asList("Elemento 1", "Elemento 2", "Elemento 3");
}
}
Clase Main para Ejecutar:
package com.ejemplo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyCollectionBean myCollectionBean = context.getBean(MyCollectionBean.class);
myCollectionBean.mostrarItems();
context.close();
}
}
En este ejemplo, estamos inyectando una lista de elementos (List<String>
) dentro del bean MyCollectionBean
usando la anotación @Autowired
.
1.3 Inyección de Colecciones Complejas
Spring también permite inyectar colecciones más complejas, como mapas o conjuntos, de forma similar a las listas. Un ejemplo de inyección de un mapa (conjunto de claves y valores) se puede hacer así:
Archivo beans.xml
con mapa:
<bean id="myMapBean" class="com.ejemplo.MyMapBean">
<property name="items">
<map>
<entry key="clave1" value="valor1"/>
<entry key="clave2" value="valor2"/>
<entry key="clave3" value="valor3"/>
</map>
</property>
</bean>
Clase Java para Map
:
package com.ejemplo;
import java.util.Map;
public class MyMapBean {
private Map<String, String> items;
public void setItems(Map<String, String> items) {
this.items = items;
}
public void mostrarItems() {
items.forEach((clave, valor) -> System.out.println(clave + " = " + valor));
}
}
1.4 Inyección de Conjuntos (Set
)
Si lo que deseas es inyectar un conjunto (sin duplicados y sin orden), la configuración será muy similar:
Archivo beans.xml
con conjunto (Set
):
<bean id="mySetBean" class="com.ejemplo.MySetBean">
<property name="items">
<set>
<value>Elemento A</value>
<value>Elemento B</value>
<value>Elemento C</value>
</set>
</property>
</bean>
Clase Java para Set
:
package com.ejemplo;
import java.util.Set;
public class MySetBean {
private Set<String> items;
public void setItems(Set<String> items) {
this.items = items;
}
public void mostrarItems() {
items.forEach(item -> System.out.println(item));
}
}
2. Uso de Colecciones con @Value
También puedes usar la anotación @Value
para inyectar colecciones desde el archivo de propiedades. Esto es útil si quieres que los valores de la colección provengan de un archivo de propiedades.
Archivo application.properties
:
items=Elemento1,Elemento2,Elemento3
Clase Java:
package com.ejemplo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Arrays;
@Component
public class MyCollectionBean {
private List<String> items;
@Value("#{'${items}'.split(',')}")
public void setItems(List<String> items) {
this.items = items;
}
public void mostrarItems() {
items.forEach(item -> System.out.println(item));
}
}
En este caso, la propiedad items
se obtiene del archivo application.properties
, y luego se convierte en una lista utilizando el split()
.
Ejercicios para Practicar
- Ejercicio 1: Crea una aplicación de Spring que inyecte una lista de números enteros (debe ser de tipo
List<Integer>
) y los imprima ordenados. - Ejercicio 2: Modifica el ejemplo anterior para inyectar un conjunto (
Set<String>
) de nombres y ordenarlos al imprimirlos, si es posible. - Ejercicio 3: Crea un bean de tipo
Map<String, Integer>
para almacenar el nombre de una persona y su edad. Inyecta este mapa en un bean y muestra las claves y valores en la consola. - Ejercicio 4: Usa un archivo de propiedades para definir una lista de ciudades, y luego inyecta esta lista en un bean y muestra las ciudades en la consola.