Inyeccción dependencias

La inyección de dependencias (DI) es el proceso en que, el Contenedor Spring provee(inyecta) beans a otros beans. La DI permite resolver las dependencias definidas por los objetos (es decir, los otros objetos con los que trabajan).

Tenemos tres formas para realizar inyección de dependencias en Spring:

  • Utilizando método constructor : para  definir dependencias obligatorias
  • Utilizando método setter : para definir dependencias opcionales
  • Cableado Automático (Autowiring): aplicable por constructor, propiedad o método setter. Simplifica las dos formas anteriores.

La DI permite el desacoplamiento del código, ya que los objetos no buscan sus dependencias ni tampoco conocen con exactitud el tipo de objeto que el Contenedor Spring inyectara.

Spring recomienda utilizar interfaces o clases abstractas para implementar inyección de dependencias, esto no es obligatorio.

Ejemplo

Vamos a crear un proyecto nuevo, que permita crear los beans Esfero y Tinta (de varios colores), donde Esfero podrá cambiar de Tinta implementando inyección de dependencias mediante el método constructor.

Para configurar los metadatos  del contenedor Spring, vamos a seguir utilizando el formato XML con el propósito de transmitir conceptos y características clave del contenedor Spring.

Crear Proyecto

Creamos un proyecto con Maven con los siguientes datos:

  • groupId: com.curso.spring
  • artifactId: app-esfero

Agregar dependencia 

En el pom.xml añadimos la siguiente dependencia Spring:

<dependencies> 
	<dependency> 	
        	<groupId>org.springframework</groupId>
            	<artifactId>spring-context</artifactId>
            	<version>5.3.15</version>
	</dependency > 

</dependencies> 

Interface Tinta

package com.curso.spring;
  
public interface Tinta {
	
	void color();
}

Clase TintaNegra

Implementamos la interface Tinta y sobrescribimos el metodo color()

package com.curso.spring;

public class TintaNegra implements Tinta{
	
   	 @Override
	public void color(){
    	System.out.println("Tinta negra");  
    }
}

Clase Esfero

Creamos la clase Esfero y establecemos una dependencia hacia Tinta mediante constructor.

package com.curso.spring;

public class Esfero{
	private Tinta tinta;
    
	public  Esfero(Tinta tinta){
    		this.tinta = tinta;
    	}    
	public void verColor(){
    		tinta.color();
    	
    	}
}

Configurar contenedor Spring

Archivo applicationContext.xml dentro de src/main/resources/META-INF/ .

<?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
    			 https://www.springframework.org/schema/beans/spring-beans.xsd">

	
	<bean id="miTinta" class="com.curso.spring.TintaNegra"> </bean>   
    
	<bean id="miEsfero" class="com.curso.spring.Esfero"> 		
            <constructor-arg  ref="miTinta" > </constructor-arg> 
        
        </bean>
    			  
</beans>

Creamos los beans miTinta y miEsfero,  utilizamos <constructor-arg > para inyectar  mediante constructor  al bean miEsfero el bean el referenciado en el atributo ref(miTinta).

Clase Principal TestEsfero

Creamos una instancia del contenedor Spring, utilizamos  ClassPathXmlApplicationContext

package com.curso.spring;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestEsfero {

	public static void main(String [] args){
    	
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/applicationContext.xml");

	Esfero esfero = context.getBean("miEsfero", Esfero.class);

	esfero.verColor();

	context.close(); 
    }
}

Obtenemos el bean miEsfero mediante getBean(...), este método recibe dos parametros, el primero es id del bean y el segundo el tipo del bean, con este método evitamos realizar un casting de tipo.

Salida Consola

 Tinta negra

Cambiar de Tinta

Creamos dos clases más, TintaAzul y TintaRoja, ambas implementan la interfaz Tinta

public class TintaAzul implements Tinta{
   	 @Override
	public void color(){
    		System.out.println("Tinta azul"); 
    }
}

public class TintaRoja implements Tinta{
   	 @Override
	public void color(){
    		System.out.println("Tinta roja");  
    }
}

Contenedor Spring

Creamos los beans para TintaAzul y TintaRoja.

 <beans>
  	<--bean anterior miTinta-->
	<bean id="miTintaAzul" class="com.curso.spring.TintaAzul"> </bean> 
	<bean id="miTintaRoja" class="com.curso.spring.TintaRoja"> </bean>  
    
    	<bean id="miEsfero" class="com.curso.spring.Esfero"> 		
            <constructor-arg  ref="miTintaAzul" > </constructor-arg> 
        
        </bean>
    			  
</beans>

Cambiamos el tipo de dependencia para el bean miEsfero, ahora le inyectamos el bean miTintaAzul, puedes ir probando con los otros beans creados. Te recomiendo que crees más implementaciones de Tinta y nuevos beans para que vallas familiarizándote con este tema.

Finalmente, ejecuta la clase principal TestEsfero y notarás como cambia el mensaje de salida en la consola.

¡Hasta pronto 👋👍!

Comentarios

Entradas populares de este blog

JWT (Json Web Token)

Instalar Java Developmet Kit(JDK)

Curso de Spring