En el desarrollo con Spring Framework, la inyeción de dependencias es un concepto fundamental. Este artículo explora en detalle las anotaciones @Autowired y @Resource para inyectar beans, proporcionando ejemplos prácticos y comparaciones clave.
Escenario práctico
Consideremos un escenario donde una persona tiene mascotas, como un gato y un perro. Vamos a implementar esto usando inyección de dependencias con anotaciones.
Clase Gato:
package com.ejemplo;
public class Gato {
public void gritar() {
System.out.println("¡Miau~");
}
}
Clase Perro:
package com.ejemplo;
public class Perro {
public void gritar() {
System.out.println("¡Guau~");
}
}
Clase Persona con inyección de dependencias:
package com.ejemplo;
import javax.annotation.Resource;
public class Persona {
private String nombre;
@Resource(name = "gatoDomestico")
private Gato mascotaGato;
@Resource(name = "perroLindo")
private Perro mascotaPerro;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Gato getMascotaGato() {
return mascotaGato;
}
public void setMascotaGato(Gato mascotaGato) {
this.mascotaGato = mascotaGato;
}
public Perro getMascotaPerro() {
return mascotaPerro;
}
public void setMascotaPerro(Perro mascotaPerro) {
this.mascotaPerro = mascotaPerro;
}
@Override
public String toString() {
return "Persona{" +
"nombre='" + nombre + '\'' +
", mascotaGato=" + mascotaGato +
", mascotaPerro=" + mascotaPerro +
'}';
}
}
Clase de prueba:
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ejemplo.Persona;
public class PruebaSpring {
@Test
public void verificarInyeccion() {
ApplicationContext contexto = new ClassPathXmlApplicationContext("configuracion.xml");
Persona persona = contexto.getBean("usuarioTest", Persona.class);
persona.getMascotaGato().gritar();
persona.getMascotaPerro().gritar();
}
}
Archivo de configuración Spring (configuracion.xml):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<bean id="gatoDomestico" class="com.ejemplo.Gato"></bean>
<bean id="gatoSalvaje" class="com.ejemplo.Gato"></bean>
<bean id="perroLindo" class="com.ejemplo.Perro"></bean>
<bean id="perroGrande" class="com.ejemplo.Perro"></bean>
<bean id="usuarioTest" class="com.ejemplo.Persona"></bean>
</beans>
Consideraciones importantes
Para habilitar la anotación en Spring, se deben incluir los espacois de nombres y restricciones en el archivo XML:
<beans xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
Además, se requiere la configuración de anotaciones de contexto:
<context:annotation-config />
Comparación entre @Autowired y @Resource
Ambas anotaciones facilitan la inyección de beans, pero presentan diferencias clave:
- Origen:
@Autowiredes una anotación específica de Spring, mientras que@Resourcepertenece a la especificación Java EE (javax.annotation). - Modo de inyección: Por defecto,
@Autowiredusa inyección por tipo (ByType), y@Resourceusa inyección por nombre (ByName). - Funcionalidad adicional: Cuando existen múltiples beans del mismo tipo, se puede usar
@Autowiredcon@Qualifierpara especificar el bean deseado, o@Resourcecon el atributoname. - Opcionalidad:
@Autowired(required = false)permite que una dependencia sea opcional, evitando excepciones si el bean no está disponible.