La inyección de dependencias es un patrón de diseño que tiene como objetivo tomar la responsabilidad de crear las instancias de las clases que otro objeto necesita y suministrárselo para que esta clase los pueda utilizar.
¿Qué es la inyección de dependencias entre clases?
Habitualmente nuestras clases dependen de otras para funcionar.
Por ejemplo, una clase que necesita buscar un registro en la base de datos necesitará de otra que se encargue de buscarlo.
Pensemos en estas dos clases. Llamemos a la primera CassA que es la cargada de tomar decisiones sobre el negocio y a la segunda ClassB, la cual se encargará de acceder a la base de datos.
En la inyección de dependencias ‘alguien’ externo se encarga de las dependencias que las clases necesitan…
La clase ClassA depende de la clase ClassB para lograr el acceso a los datos en la base de datos.
Aquí ‘normalmente’ en la la ClassA creariamos la ClassB . La ClassA sería la responsable de crear a la ClassB.
La Inversión de control en Spring
Spring maneja el concepto de IoC (Inversion of Control) ocupándose de mantener en su ‘contexto’ todas las instancias de nuestra aplicación y de inyectarle esa instancia a quien la necesite.
Spring llama a estas instancias beans .
Los bean son las instancias de las clases que están disponibles para ser reutilizados y son gestionados dentro del contenedor de Spring.
IoC es el trabajo que realiza Spring buscando estas dependencias entre los objetos y realizando el ‘set’ estos beans en quien los requiera.
Spring sabe qué dependencias existen entre las instancias y se encarga de satisfacerlas.
Busca en su contenedor de beans la instancia adecuada y se la agrega al objeto cumpliendo así con la inyección de dependencias.
Como realizamos la inyección de dependencias con Spring
Spring nos da diferentes modos para inyectar las dependencias.
La más común y más recomendada es mediante el uso de anotaciones.
La anotación general para indicar que queremos que una clase sea gestionada por el contenedor de Spring es @Component .
Al anotar nuestra clase con @Component le decimos a Spring que deseamos que esa clase sea un bean .
Por lo tanto será Spring el que hará un new de la clase y creará la instancia.
@Component
public class ClassB {
public void doSomething() {
System.out.println("working");
}
}
Nuestra clase ClassA necesita a la ClassB .
Spring se da cuenta de esta dependencia porque nuestra clase es un componente que a su vez tiene en su constructor a la ClassB .
Será Spring el que cree la ClassB y luego al instanciar la ClassA le pase en el parámetro del constructor esa dependencia
@Component
public class ClassA {
private final ClassB classB;
public ClassA(ClassB classB) {
this.classB = classB;
}
public void doSomething() {
System.out.println("working");
classB.doAnotherJob();
}
}
Cuáles son las ventajas de la Inyección de dependencias
Mayor cohesión y menor acoplamiento:
Siempre que construimos una aplicación debemos pensar en reducir el acoplamiento entre las clases y aumentar la cohesión.
Esto significa que cada clase debe tener una única responsabilidad, debe ser bien específica en dicha responsabilidad y hacerla bien (cohesión).
Por la reducción del acoplamiento refiere a que los cambios en una clase no deberían impactar en otra.
Al crear nuestras clases sabiendo que Spring será el encargado de crearlas y de inyectarlas, nos libera para enfocarnos solamente en la funcionalidad de nuestra clase en construcción.
Creamos nuestra clase y definimos sus responsabilidades pensando solo en el ámbito de esa clase. Establecemos cuáles serán los métodos de esa clase para que puedan ser utilizados por otras, pero sin estar pendientes de otras clases.
Reutilización:
Una clase está pensada en ser reutilizable por quien la necesite.
Una clase responsable del acceso a la base puede ser utilizada por otras a través del contrato definido en sus métodos y ser inyectada en todas aquellas que necesiten el acceso a la base de datos.
Cambios de arquitectura:
Al diseñar las clases pensando en su interfaz. Podemos realizar cambios internos mientras mantengamos el contrato de la clase sin afectar a otras que la están usando.
Pruebas:
Las pruebas unitarias sobre las clases es mucho más simple, pudiéndose utilizar mocks para aquellas que no son del ámbito de la prueba puntual.
Conclusión
Entendimos el concepto de dependencia y de IoC y como Spring nos ayuda con la gestión de todas las dependencias entre clases dentro de nuestra aplicación. Vimos que utilizando Spring podemos ocuparnos de crear nuestras clases pensando solo en su lógica y dejando la tarea de las dependencias en Spring. Entendimos la utilidad de IoC y sus ventajas.