injection spring dependency-injection

spring - injection - Setter DI vs Constructor DI en la primavera?



di spring (7)

La primavera tiene dos tipos de DI: setter DI y DI de construcción.

El DI basado en el constructor corrige el orden en el que se deben inyectar las dependencias. Setter basado en DI no ofrece esto.

La DI basada en Setter nos ayuda a inyectar la dependencia solo cuando se requiere, en lugar de requerirla en el momento de la construcción.

No veo ninguna otra diferencia significativa, ya que ambos tipos de Spring DI ofrecen las mismas características: tanto el definidor como el constructor DI inyectan la dependencia cuando se inicia el código. Por supuesto, el constructor DI lo hará a través del constructor, mientras que el configurador DI lo hará a través de un configurador justo después de construir el objeto, pero no hace ninguna diferencia para el desarrollador en términos de rendimiento, etc. Ambos también ofrecen medios para especificar el orden de inyección de dependencia también.

Estoy buscando un escenario donde uno proporciona una ventaja distinta sobre el otro o donde un tipo es completamente inutilizable.


Cuando se trata de los pros y los contras específicos de la primavera:

  • La inyección de constructor (de la definición) no le permite crear dependencias circulares entre beans. Esta limitación es en realidad una ventaja de la inyección del constructor: Spring puede resolver dependencias circulares cuando se usa la inyección de setter sin que te des cuenta.

  • Por otro lado, si usa la inyección del constructor, CGLIB no puede crear un proxy, lo que le obliga a usar proxies basados ​​en interfaz o un constructor ficticio sin argumentos. Ver: SPR-3150


Debe decidir basándose en consideraciones de diseño, no en consideraciones de herramientas (Spring). Desafortunadamente, Spring nos ha entrenado para usar la inyección de setter porque cuando fue concebida originalmente, no existía una "anotación" en Java, y en XML, la inyección de setter funciona y se ve mucho mejor. Hoy, estamos liberados de esas restricciones, lo que permite que sea una decisión de diseño nuevamente. Sus beans deben usar la inyección de constructor para cualquier dependencia que requiera la inyección de bean y setter para las dependencias que son opcionales y tienen un valor predeterminado razonable, más o menos como lo ha estado diciendo OOD desde el principio.


Prefiero la inyección de setter.

Piense en lo que sería sin la primavera (como señaló Ryan). ¿Pasarías las dependencias en constructor? Si hay demasiadas dependencias esto parece mal. Por otro lado, el constructor se puede utilizar para imponer el estado válido del objeto: requiere todas las dependencias y verifica si no son nulas.

Los proxies son otra cosa (como señaló Tomasz): necesitarás un constructor ficticio que anule toda la idea.

Hay una tercera opción por cierto - inyección de campo. Tiendo a usar eso, aunque no es una decisión de diseño tan buena, porque guarda un setter adicional, pero si se usa fuera de la primavera, tendré que agregar el setter.


Según el contenido de spring.io a partir de la primavera 5 en adelante

Ya que puede mezclar DI basada en constructor y basada en establecedor, es una buena regla general usar constructores para dependencias obligatorias y métodos de configurador o métodos de configuración para dependencias opcionales. Tenga en cuenta que el uso de la anotación @Required en un método de establecimiento se puede usar para hacer de la propiedad una dependencia requerida.

El equipo de Spring generalmente recomienda la inyección de constructores, ya que permite implementar componentes de aplicaciones como objetos inmutables y garantizar que las dependencias necesarias no sean nulas. Además, los componentes inyectados por el constructor siempre se devuelven al código del cliente (llamante) en un estado completamente inicializado. Como nota al margen, un gran número de argumentos de constructor es un mal olor de código, lo que implica que la clase probablemente tenga demasiadas responsabilidades y debería ser refactada para abordar mejor la separación adecuada de las preocupaciones.

La inyección de Setter se debe usar principalmente solo para dependencias opcionales a las que se les puede asignar valores predeterminados razonables dentro de la clase. De lo contrario, las comprobaciones no nulas se deben realizar en todos los lugares en que el código utiliza la dependencia. Uno de los beneficios de la inyección de setter es que los métodos de setter hacen que los objetos de esa clase puedan reconfigurarse o reinyectarse más tarde. La administración a través de JMX MBeans es, por lo tanto, un caso de uso convincente para la inyección de incubadores.

Aquí está el link para la cita anterior

Pero, todos los tipos de inyecciones están disponibles y ninguno de ellos está en desuso. En un nivel alto, obtiene la misma funcionalidad en todos los tipos de inyección.

En resumen, elija el tipo de inyección que mejor se adapte a su equipo y proyecto.

Las recomendaciones del equipo de Spring y las publicaciones de blog independientes variarán con el tiempo. No hay una regla dura y rápida.

Si el equipo de Spring no recomendó un estilo de inyección en particular, lo marcarían como obsoleto u obsoleto. Ese no es el caso con ninguno de los estilos de inyección.


Ya que puedes mezclar ambos,
Constructor DI - y DI basada en Setter ,
Es una buena regla general usar argumentos de constructor para dependencias obligatorias y configuradores para dependencias opcionales .


Tenga en cuenta que el uso de una anotación @Required en un configurador se puede utilizar para hacer dependientes dependencias requeridas.


no, incluso la Inyección Constructor ocurre, la inyección sigue funcionando, pero solo la inicialización es limitada, la inyección del fijador es opcional y flexible pero puede generalmente para la clase de parámetro, un frijol de primavera con otros frijoles de primavera


Inyección del constructor: Estamos inyectando las dependencias a través del constructor.

Generalmente podemos utilizar para dependencias obligatorias.

Si utiliza la inyección de Constructor, existe una desventaja llamada "Dependencia circular".

Dependencia circular: Supongamos que A y B. A depende de B. B depende de A. En este constructor, la inyección fallará. En ese momento la inyección de Setter es útil.

Si el estado del objeto no es inconsistente, no creará el objeto.

Inyección de Setter: estamos inyectando las dependencias a través de los métodos de Setter.

Esto es útil para dependencias no obligatorias.

Es posible volver a inyectar dependencias usando la inyección de Setter. No es posible en la inyección de Constructor.