La configuración de beans en Spring usando XML se basa en el elemento <bean>, donde el atributo class especifica la clase Java. Esta aproximación permite declarar tanto beans simples como beans con dependencias, inyectadas a través de constructores o métodos setter.
Declaración de un Bean Simple
Un bean simple se define proporcionando su clase. Spring se encarga de instanciarlo. La configuración XML es análoga a una clase de configuración de Java anotada con @Configuration, y cada elemento <bean> equivale al uso de @Bean.
package demo.spring.musica;
public class AlbumMusical {
private final String artista = "Los Átomos";
private final String cancion = "Fusión Nuclear";
public void reproducir() {
System.out.printf("Reproduciendo \"%s\" de %s%n", cancion, artista);
}
}
El archivo XML contexto-app.xml declara el bean:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<bean id="miAlbum" class="demo.spring.musica.AlbumMusical"/>
</beans>
Para probar la configuración, se carga el contexto:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.junit.jupiter.api.Test;
public class PruebaReproductor {
@Test
void deberiaCrearAlbumSimple() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("contexto-app.xml");
AlbumMusical album = ctx.getBean("miAlbum", AlbumMusical.class);
album.reproducir(); // Salida: Reproduciendo "Fusión Nuclear" de Los Átomos
}
}
Inyección de Dependencias vía Constructor
Para inyectar dependencias mediante el constructor, la clase debe definir un constructor que las acepte. En XML, se usa el elemento <constructor-arg>.
Inyección por Referencia
Se inyecta una referencia a otro bean usando el atributo ref.
package demo.spring.musica;
public class ReproductorCD {
private final AlbumMusical disco;
public ReproductorCD(AlbumMusical disco) {
this.disco = disco;
}
public void escuchar() {
disco.reproducir();
}
}
<bean id="albumRef" class="demo.spring.musica.AlbumMusical"/>
<bean id="reproductor" class="demo.spring.musica.ReproductorCD">
<constructor-arg ref="albumRef"/>
</bean>
Inyección de Valores Literales
Se inyectan valores de tipo String u otros primitivos usando el atributo value.
package demo.spring.musica;
public class AlbumVacio {
private final String titulo;
private final String artista;
public AlbumVacio(String titulo, String artista) {
this.titulo = titulo;
this.artista = artista;
}
public void mostrar() {
System.out.println(titulo + " - " + artista);
}
}
<bean id="albumPersonal" class="demo.spring.musica.AlbumVacio">
<constructor-arg name="titulo" value="Mundo Cuántico"/>
<constructor-arg name="artista" value="Científicos del Rock"/>
</bean>
Inyección de Colecciones
Se pueden inyectar listas (<list>), conjuntos (<set>) o mapas. Los elementos de la colección pueden ser literales (<value>) o referencias (<ref>).
package demo.spring.musica;
import java.util.List;
public class AlbumMultiple {
private final List<String> pistas;
private final List<AlbumMusical> bonusDiscos;
public AlbumMultiple(List<String> pistas, List<AlbumMusical> bonusDiscos) {
this.pistas = pistas;
this.bonusDiscos = bonusDiscos;
}
public void reproducirTodo() {
pistas.forEach(p -> System.out.println("Pista: " + p));
bonusDiscos.forEach(AlbumMusical::reproducir);
}
}
<bean id="albumExtra1" class="demo.spring.musica.AlbumMusical"/>
<bean id="coleccionAlbum" class="demo.spring.musica.AlbumMultiple">
<constructor-arg>
<list>
<value>Intro</value>
<value>Canción Principal</value>
</list>
</constructor-arg>
<constructor-arg>
<list>
<ref bean="albumExtra1"/>
</list>
</constructor-arg>
</bean>
Inyección de Dependencias vía Setter
La inyección por setter requiere que la clase expone métodos setter públicos para sus dependencias. En XML, se utiliza el elemento <property>.
package demo.spring.musica;
import java.util.List;
public class AlbumConfigurable {
private AlbumMusical discoPrincipal;
private String nombre;
private List<String> colaboradores;
private List<AlbumMusical> discosRelacionados;
// Todos los setters necesarios
public void setDiscoPrincipal(AlbumMusical disco) { this.discoPrincipal = disco; }
public void setNombre(String nombre) { this.nombre = nombre; }
public void setColaboradores(List<String> lista) { this.colaboradores = lista; }
public void setDiscosRelacionados(List<AlbumMusical> lista) { this.discosRelacionados = lista; }
public void informar() {
System.out.println("Álbum: " + nombre);
if (discoPrincipal != null) discoPrincipal.reproducir();
if (colaboradores != null) colaboradores.forEach(c -> System.out.println("Colaborador: " + c));
}
}
<bean id="albumBase" class="demo.spring.musica.AlbumMusical"/>
<bean id="albumConfigurable" class="demo.spring.musica.AlbumConfigurable">
<property name="discoPrincipal" ref="albumBase"/>
<property name="nombre" value="Álbum Experimental"/>
<property name="colaboradores">
<list>
<value>Dr. Efectos</value>
<value>Maestro Sonido</value>
</list>
</property>
<property name="discosRelacionados">
<list>
<ref bean="albumBase"/>
</list>
</property>
</bean>