¿Qué es la inyección de dependencias y por qué es importante?
La inyección de dependencias es un principio clave en el desarrollo de software moderno que busca desacoplar las clases de las implementaciones que utilizan, promoviendo así el principio de inversión de control. Al pasar las dependencias a la clase en vez de crearlas internamente, se reduce el acoplamiento y se incrementa la flexibilidad y facilidad de mantenimiento del código.
¿Cómo implementa Spring la inyección de dependencias?
Spring, un marco de trabajo popular para el desarrollo de aplicaciones en Java, implementa la inyección de dependencias utilizando su contenedor de inversión de control. Este contenedor toma el control de la creación y gestión de instancias de los objetos necesarios para el funcionamiento de la aplicación.
Autowire en Spring: Spring facilita la inyección de dependencias mediante la anotación @Autowired. Al usar esta anotación, se indica que el control de la creación de instancias será delegado al contenedor de Spring. Esto hace transparente el proceso de inyección de dependencias para el desarrollador, quien no tendrá que preocuparse por la creación manual de objetos.
¿Por qué es crucial utilizar correctamente los componentes de Spring?
Un aspecto esencial al inyectar dependencias en Spring es asegurarse de que las clases o atributos que se desean inyectar sean componentes reconocidos por el framework. En otras palabras, deben ser beans de Spring.
Ejemplo de uso: Consideremos un repositorio que extiende de CrudRepository. Al extenderlo, automáticamente se marca como un componente de Spring, permitiendo así ser inyectado. Del mismo modo, si se utiliza una clase decorada con anotaciones específicas de otra biblioteca, como MapStruct, es importante verificar que el componente o su modelo sea compatible para ser gestionado por Spring.
¿Cómo ayuda este enfoque a mejorar el desarrollo?
La inyección de dependencias automatizada elimina la necesidad de crear objetos manualmente, lo que puede ser propenso a errores y difícil de mantener. Al confiar en el framework de Spring para gestionar estas instancias, los desarrolladores pueden concentrarse en la lógica de negocio de sus aplicaciones, asegurando un código más limpio y eficiente.
Ejemplos prácticos y recomendaciones
Veamos un ejemplo de cómo se evita el error común del "null pointer exception" en Java gracias a la inyección de dependencias de Spring:
Verificar componentes: Asegúrate de que las clases a inyectar son parte del ecosistema de Spring para evitar problemas.
Utilizar anotaciones adecuadas: Aprovecha las anotaciones que ofrece Spring, como @Component, @Service, @Repository, para que el contenedor pueda identificar y gestionar tus beans.
Evitar el acoplamiento excesivo: La inyección de dependencias promueve la creación de un código modular y más fácil de mantener, crucial para proyectos de gran escala.
Este principio no solo fomenta prácticas de codificación limpias, sino que también ofrece beneficios tangibles en la gestión y escalabilidad del software. Usar la inyección de dependencias de manera eficiente es clave para el desarrollo ágil y sostenible.
Inversión de dependencias no es lo mismo que inyección de dependencias.
Responsability*
Inyección de dependencias: pasar la dependencia a la clase que lo va a utilizar en lugar de crearla internamente dentro esa clase. Esto con el fin de no acoplar la clase a la implementación que esta utilizando.
Inversión de control: es un framework quien toma control de los objetos. En este caso Spring. El cual se encarga de crear y administrar instancias de objetos que se conocen como builds o componentes.
Entonces Spring usa la notación @Autowired para la inyección de dependencias.
Hay que corregir el video, Solid no tiene inyeccion de Dependencias tiene es Inversion de dependencias, la cual es basada en relaciones abstractas, como lo consigues usando injeccion pero no son lo mismo y Solid no lo tiene como principio.
Totalmente, genera confusión, lo reporté
Excelente explicacion, yo lo hacia porque un dia me dijeron que se debia hacer y ya. Me ha gustado mucho este curso.
Verdad que si
Al agregar el @Autowired al ProductMapper me dice q ningun bean autowired se encontro en ProductMapper
Could not autowire,No beans of 'ProductMapper' type found
Usaste la anotación @Mapper(componentModel = "spring") en la interface ProductMapper?
También me sale el mismo error
Hola!!, Es buena práctica crear un Bean para un objeto como Gson, SimpleDateFormat o funciones globales?
Por ejemplo, llegué a ver en GitHub que algunos proyectos generaban el siguiente Bean:
@Bean Gson gson() { return new Gson(); }O también:@Bean SimpleDateFormat simpleDateFormat() { return new SimpleDateFormat("dd-MM-yyyy"); }
Y después lo inyectaban en otras clases, en lugar de crear nuevamente el objeto, hacer esto es bueno??
Me encanta tu pregunta Carina! Me da posibilidad de explicar algo que muchas veces hacemos sin saber.
Para contextualizar: Cuando se crea un @Bean se registra una ÚNICA instancia de esa clase para nuestra aplicación en todo el contexto de Spring.
Generar un bean es una buena práctica SI Y SÓLO SI la clase que deseamos anotar con @Bean es de hilo seguro (Thread safe).
Algo que yo hago para rápidamente saber sí una clase es thread safe es buscar en Google "<Clase> thread safe", por ejemplo: "Gson thread safe" ó "SimpleDateFormat thread safe". Así me doy cuenta que Gson es thread safe y puede tener la anotación @Bean para luego inyectarla con @Autowired, peeeero SimpleDateFormat no lo es y por lo tanto sería una pésima práctica ponerle la anotación @Bean.
Que un objeto de una clase que no es thread safe tenga la anotación @Bean puede generar problemas de concurrencia si varios hilos usan dicha instancia única al mismo tiempo.
Espero esto te sea de utilidad!
Me sale el siguiente error en respuestas anteriores dicen que cheque los getter y stter poir favor explicar bien sus respuestas sin utilizar lombok ya que eso no se esat usando en los videos gracias de antemano.
Tengo el mismo error, no sé cuál sea la solución.
tengo el mismo error
Solid
Single responsability
Open-closed
Liskov sustitution
Interface segregation
Dependency injection
Si les aparece error de los atributos "productos" y "categoria" no se preocupen por ahora, en la clase "26. Implementar la anotación @RestController" Jose comparte la solución
se pone complicada la cosa xD
todo empezon en el mapstruck
Hola, ¿cual es el ciclo de vida de cada instancia inyectada? ¿scope por defecto?
Se puede generar la inyencción de dependencias a través de un constructor, ¿cúal es mejor practica, que sea por campo o que sea por constructor?
Es una muy buena pregunta, Paloma!
Existen tres maneras de usar la inyección dependencias con @Autowired: En el atributo, en el constructor y en el método set. En este articulo puedes ver cómo se usa cada uno y sus diferencias.
A pesar de que hacerlo en el atributo (Field-based) es lo más práctico, elegante y la manera en que mejor se lee; lo mejor es hacerlo en el constructor (Constructor-based) para poder declarar los atributos inyectados como final para que sean inmutables, y además es muy recomendado para declarar dependencias obligatorias. Asimismo se evita que la dependencia en un momento determinado pueda ser null.
Wooow, jamas había entendido que son los beans y las dependencias. Este video se merece un 10/10
Hola a todos, he disfrutado mucho del curso.
Queria compartirles el error que me sucedia a mi, por si a alguien le pasa lo mismo, puede ser algo tonto, pero si a alguien le pasa lo mismo que tenga esto en cuenta, en el producMapper estamos usando el mapper de categoria, pero este mapeo no funciona si categoria no tiene getters y setters en la clase Producto, saltara un error de que no encuentra el atributo categoria.
Saludos.
A quienes les salga error con eclipse y mapstructs
lo solucioné con dos cosas:
Clic derecho sobre el proyecto -> propiedades -> Java Compiler -> Annotation Processing ->
Se debe checkear Enable project specific settings
Clic derecho sobre el proyecto -> propiedades -> Java Compiler -> Annotation Processing -> Factory Path ->
Se debe checkear Enable project specific settings
-> Add External Jar -> Aquí buscar el jar del plugin es una ruta similar:
C:\Users\pepito.gradle\caches\modules-2\files-2.1\org.mapstruct\mapstruct-processor\1.4.2.Final\e55bd90d51cddd638c07d5bd89fc7535d4e3d069\mapstruct-processor-1.4.2.Final
Ahora Aplicar y Cerrar
SOLID hace referencia a la Inversion de Dependencia, que no es lo mismo (aunque si tiene que ver) con la** inyeccion de dependencia** que ofrese Spring. Por otro lado, la Inversion de control tiene que ver con el "Principio Holliwood" (no nos llames, nosotros te llamamos) y no se limita solo a la inyeccion de dependencias....para ampliar un poco simplementeo, espero que sirvan los comentarios. Muy buen curso !!
¡Incrible!, no entendía el porque aveces mi API soltaba errores y siempre tenía que ver con las anotaciones además de la inyección de dependencias. Ahora sé que es necesario que hagan parte de Spring para inyectar las dependecias.
¡Gracias!
Hola, que pasa al usar el @AutoWired pero la interface tiene varias implementaciones? Spring como sabe cual de todas las implementaciones se debe inyectar?
Cuando hay 2 clases que tienen la misma implementación podemos usar Qualifier para clasificar las clases:
@Repository@Qualifier("persona2")//nombramos la clase con la implementacionpublicclassPersonaRepoImplimplementsIpersonaRepo{ @Overridepublicvoidregistrar(String nombre){//registro}}
y para seleccionarla seguimos la misma metodología
@ServicepublicclassPersonaServiceImplimplementsIPersonaService{ @Autowired @Qualifier("persona2")// ponemos como eleccion a la clase con persona2 privateIpersonaRepo repo; @Overridepublicvoidregistrar(String nombre){ repo.registrar(nombre);}}
Perfecto. Muchas gracias!
ME sale este error al hacerle inyección a private Product mapper de Producto Repositorio
Could not autowire. There is more than one bean of 'ProductMapper' type.