java - ejemplo - ¿Qué es exactamente la inyección de campo y cómo evitarla?
jlabel netbeans (3)
Leí en algunas publicaciones sobre
Spring MVC
y
Portlets
que no se recomienda la inyección de campo.
Porque estoy tratando de obtener una Entonces me pregunté si estoy usando
inyección de campo
y no puedo responder.
Según tengo entendido, la
inyección de campo
es si inyecta un
Bean
en un atributo con
@Autowired
esta manera:
CartController.java:
...
@Autowired
private Cart cart;
...
BookshopConfiguartion.java:
@Configuration
public class BookShopConfiguration {
@Bean
public Cart cart(){
return new Cart();
}
//more configuration
My
Cart.java
se utiliza para almacenar y proporcionar información sobre los libros en el carrito.
Durante mi investigación leí sobre la inyección de constructores :
MyComponent.java:
...
public class MyComponent{
private Cart cart;
@Autowired
public MyComponent(Cart cart){
this.cart = cart;
}
...
¿Cuáles son las ventajas y las desventajas de ambos tipos de inyecciones?
EDITAR 1: como esta pregunta está marcada como duplicada de esta pregunta, la revisé. Porque no hay ejemplos de código ni en la pregunta ni en las respuestas, no me queda claro si estoy en lo cierto al adivinar qué tipo de inyección estoy usando.
Cuestion de gusto. Es tu decisión.
Pero puedo explicar por qué nunca uso la inyección de constructor .
-
No quiero implementar un constructor para todos mis
@Service
,@Repository
y@Controller
. Quiero decir, hay alrededor de 40-50 frijoles o más. Cada vez que agrego un nuevo campo tendría que extender el constructor. No. No lo quiero y no tengo que hacerlo. -
¿Qué sucede si su Bean (Servicio o Controlador) requiere que se inyecten muchos otros beans? Un constructor con 8 parámetros es muy feo.
-
Si estoy usando CDI, el constructor no me concierne.
EDITAR : Vojtech Ruzicka dijo:
la clase tiene demasiadas dependencias y probablemente está violando el principio de responsabilidad única y debe ser refactorizada
Sí.
Teoría y realidad.
Aquí hay un ejemplo:
DashboardController
asignado a una sola ruta
*:8080/dashboard
.
My
DashboardController
recopila una gran cantidad de información de otros servicios para mostrarlos en una página de información general del tablero / sistema.
Necesito este único controlador.
Entonces, tengo que asegurar solo esta ruta (autenticación básica o filtro de rol de usuario).
Esta es una de las discusiones interminables en el desarrollo de software, pero los principales influyentes en la industria se están volviendo más obstinados sobre el tema y comenzaron a sugerir la inyección de constructores como la mejor opción.
Inyección de constructor
Pros:
- Mejor comprobabilidad . No necesita ninguna biblioteca simulada o un contexto Spring en las pruebas unitarias. Puede crear un objeto que desee probar con la nueva palabra clave. Tales pruebas son siempre más rápidas porque no dependen del mecanismo de reflexión. ( Esta pregunta se hizo 30 minutos después. Si el autor hubiera utilizado la inyección del constructor, no habría aparecido).
- Inmutabilidad Una vez que se establecen las dependencias, no se pueden cambiar.
- Código más seguro Después de la ejecución de un constructor, su objeto está listo para usar, ya que puede validar cualquier cosa que se haya pasado como parámetro. El objeto puede estar listo o no, no hay estado intermedio. Con la inyección de campo, se introduce un paso intermedio cuando el objeto es frágil.
- Expresión más limpia de dependencias obligatorias . La inyección de campo es ambigua en este asunto.
- Hace que los desarrolladores piensen en el diseño . dit escribió sobre un constructor con 8 parámetros, que en realidad es el signo de un mal diseño y el antipatrón del objeto de Dios . No importa si una clase tiene 8 dependencias en su constructor o en los campos, siempre está mal. Las personas son más reacias a agregar más dependencias a un constructor que a través de campos. Funciona como una señal para tu cerebro de que debes detenerte por un momento y pensar en la estructura de tu código.
Contras:
- Más código (pero los IDE modernos alivian el dolor).
Básicamente, la inyección de campo es lo contrario.
Tipos de inyección
Hay tres opciones sobre cómo se pueden inyectar dependencias en un bean:
- A través de un constructor
- A través de setters u otros métodos
- A través de la reflexión, directamente en los campos.
Está utilizando la opción 3. Eso es lo que sucede cuando usa
@Autowired
directamente en su campo.
Pautas de inyección
Una guía general, que recomienda Spring (consulte las secciones sobre DI basada en constructor o DI basada en Setter ) es la siguiente:
- Para dependencias obligatorias o cuando se busca la inmutabilidad, use la inyección del constructor
- Para dependencias opcionales o modificables, use la inyección de setter
- Evite la inyección de campo en la mayoría de los casos.
Inyecciones de inyección de campo
Las razones por las que la inyección de campo está mal vista son las siguientes:
- No puede crear objetos inmutables, como puede hacerlo con la inyección del constructor
- Sus clases tienen un acoplamiento estrecho con su contenedor DI y no se pueden usar fuera de él
- Sus clases no pueden ser instanciadas (por ejemplo, en pruebas unitarias) sin reflexión. Necesita el contenedor DI para crear instancias, lo que hace que sus pruebas se parezcan más a las pruebas de integración
- Sus dependencias reales están ocultas desde el exterior y no se reflejan en su interfaz (ya sea constructores o métodos)
- Es realmente fácil tener como diez dependencias. Si estuviera utilizando la inyección de constructor, tendría un constructor con diez argumentos, lo que indicaría que algo es sospechoso. Pero puede agregar campos inyectados usando la inyección de campo indefinidamente. Tener demasiadas dependencias es una señal de alerta de que la clase generalmente hace más de una cosa y que puede violar el Principio de responsabilidad única.
Conclusión
Dependiendo de sus necesidades, debe usar principalmente inyección de constructor o alguna combinación de inyección de constructor y setter. La inyección de campo tiene muchos inconvenientes y debe evitarse. La única ventaja de la inyección de campo es que es más conveniente escribir, lo que no supera todas las desventajas.
Otras lecturas
Escribí un artículo en el blog sobre por qué la inyección de campo generalmente no se recomienda: La inyección de dependencia de campo se considera dañina .