David Gómez Rubio

Analista funcional

Project Manager

Dirección de equipos informáticos

David Gómez Rubio

Analista funcional

Project Manager

Dirección de equipos informáticos

Artículo del Blog

Spring Framework. ¿Qué es la inyección de dependencias y cuales son sus ventajas?

Spring Framework. ¿Qué es la inyección de dependencias y cuales son sus ventajas?

Una de las características que identifican al framework Spring es la Inversión de Control. De este paradigma deriva directamente la inyección de dependencias (DI – Dependencies Injection), proceso mediante el cual los objetos definen sus dependencias a través de los argumentos del constructor, los argumentos de un método Factory o las propiedades que se establecen al instanciar un objeto.

Después, el contenedor de Spring es el encargado de inyectar esas dependencias en el momento de la creación del bean

Este proceso, da la vuelta a la forma anterior de trabajar, donde eran los Bean’s los que controlaban directamente la instanciación y ubicación de sus dependencias mediante el uso de la construcción de clases o mediante el patrón Service Locator.

Ventajas de la inyección de dependencias.

  • Inicialmente conseguimos un código mucho más limpio.
  • El desacoplamiento es mucho más efectivo porque los objetos reciben sus dependencias sin conocer ni su ubicación ni su clase.
  • Cada objeto, puede realizar más fácilmente sus pruebas unitarias de forma independiente con diferentes implementaciones simuladas.
  • Al conseguir esta independencia de las clases aumentan sustancialmente la posibilidad de ser reutilizarlas en otras partes del código promoviendo así la abstracción lógica deseada.

Para inyectar dependencias en nuestro código tenemos 2 recursos principalmente:

La DI realizada en el constructor:

Esta se realiza mediante el contenedor que invoca a un constructor con varios argumentos, cada uno de los cuales representa una dependencia.

Nota: Llamar a un método Factory static con argumentos específicos para construir el bean es casi lo mismo, ya que el contenedor lo trata de manera similar a lo que sucede en el constructor.

El siguiente ejemplo muestra una clase que solo puede inyectar su dependencia a través del constructor, la cual omite la lógica de negocio que realmente usa el BuscadorUsuario inyectado:

public class ListadoUsuario {

    // ListadoUsuario tiene dependencia con un objeto BuscadorUsuario
    private BuscadorUsuario buscadorUsuario;

    // un constructor para que el contenedor Spring pueda inyectar un 	         // BuscadorUsuario
    public ListadoUsuario(BuscadorUsuario buscadorUsuario) {
        this.buscadorUsuario = buscadorUsuario;
    }
}

Ten en cuenta que no hay nada especial en esta clase. Es un POJO (Plain Old Java Object) que no tiene dependencias en interfaces específicas del contenedor, clases base o anotaciones.

Inyección de dependencia basada en el método Setter

La DI basada en el método Setter se logra mediante los métodos de establecimiento de llamadas de contenedor en sus beans después de invocar un constructor sin argumentos o un  método Factory static sin argumentos para instanciar su bean.
El siguiente ejemplo muestra una clase que solo puede ser inyectada por dependencia mediante la inyección de setter puro. Esta clase es Java convencional. Es un POJO que no tiene dependencias en interfaces específicas del contenedor, clases base o anotaciones.

public class ListadoUsuario {

    // ListadoUsuario tiene dependencia con un objeto BuscadorUsuario
    private BuscadorUsuario buscadorUsuario;

    // Un método setter para que el contenedor Spring pueda inyectar un 	     // BuscadorUsuario
    public void setBuscadorUsuario(BuscadorUsuario buscadorUsuario) {
        this.buscadorUsuario = buscadorUsuario;
    }

    // La lógicad de negocio también se omite en este caso
}

¿Por cual me decido, constructor o setter?

Dado que puede mezclar DI’s basados ​​en constructor y en setter’s, es una buena regla general utilizar constructores para dependencias obligatorias y métodos setter o métodos de configuración para dependencias opcionales. Ten en cuenta que el uso de la anotación @Required en un método setter puede usarse para hacer que la propiedad sea una dependencia requerida; sin embargo, la inyección de constructor con validación programática de argumentos es preferible.

El equipo de Spring generalmente aconseja utilizar la inyección por constructor, ya que le permite implementar componentes de la aplicación como objetos inmutables y garantiza que las dependencias requeridas no tengan un valor null. Además, los componentes inyectados por el constructor siempre se devuelven al código del cliente que realiza la llamada en un estado completamente inicializado.

Como nota ten en cuenta que una gran cantidad de argumentos de constructor es una mala práctica porque implica que la clase probablemente tenga demasiadas responsabilidades y deberá ser modularizada para abordar mejor las tareas que tiene que resolver.

La inyección en el setter solo debe usarse principalmente para dependencias opcionales a las que se les pueden asignar valores predeterminados razonables dentro de la clase. De lo contrario, las comprobaciones por valores null deberán realizarse en todas partes donde el código use la dependencia. Una ventaja de la inyección en el setter es que, los métodos setter hacen que los objetos de esa clase sean susceptibles de reconfiguración o reinyección posterior. La administración a través de JMX MBeans es, por lo tanto, un caso de uso convincente para la inyección en el setter.

Usa el estilo DI que tenga más sentido para cada clase en particular. A veces, cuando se trata de clases de terceros, la elección tienes que hacerla tu. Por ejemplo, si una clase de terceros no expone ningún método de establecimiento, entonces la inyección de constructor puede ser la única forma disponible de DI.

Índice de contenidos Spring Boot

Taggs:
Escribe un comentario