Solución:
Sí, la opción B (que se llama inyección de constructor) se recomienda en realidad sobre la inyección de campo y tiene varias ventajas:
- las dependencias están claramente identificadas. No hay forma de olvidar uno al probar o crear una instancia del objeto en cualquier otra circunstancia (como crear la instancia de bean explícitamente en una clase de configuración)
- las dependencias pueden ser finales, lo que ayuda con la robustez y la seguridad de los subprocesos
- no necesita reflexión para establecer las dependencias. InjectMocks todavía se puede usar, pero no es necesario. Puede crear simulacros usted mismo e inyectarlos simplemente llamando al constructor
Consulte esta publicación de blog para obtener un artículo más detallado, de uno de los colaboradores de Spring, Olivier Gierke.
Te lo explicaré en palabras sencillas:
En la opción (A), está permitiendo que cualquiera (en una clase diferente fuera / dentro del contenedor Spring) cree una instancia usando el constructor predeterminado (como new SomeService()
), que NO es tan bueno como necesitas SomeOtherService
objeto (como una dependencia) para su SomeService
.
¿Hay algo más que haga el constructor autowired además de agregar código a las pruebas unitarias? ¿Es esta una forma más preferida de realizar la inyección de dependencia?
La opción (B) es el enfoque preferido ya que NO permite crear SomeService
objeto sin resolver realmente el SomeOtherService
dependencia.
Tenga en cuenta que desde Spring 4.3 ni siquiera necesita un @Autowired en su constructor, por lo que puede escribir su código en estilo Java en lugar de vincularse a las anotaciones de Spring. Su fragmento se vería así:
@Component
public class SomeService {
private final SomeOtherService someOtherService;
public SomeService(SomeOtherService someOtherService){
this.someOtherService = someOtherService;
}
}