Bien, en esta clase vamos a ver cómo inyectar, pero mediante la interfaz, desacoplar completamente
una implementación concreta como una clase.
Acá mi servicio está muy acoplado, ya que es una clase.
La clase por lo general podrían cambiar más adelante.
Podríamos tener otra clase.
Otra implementación con otro nombre.
Por lo tanto, acá el tipo de dato podría cambiar.
Y si lo estamos usando inyectando en varios controladores, habría que estar modificando uno por uno.
Entonces, por eso es mejor implementar una interfaz.
Es algo mucho más genérico, abstracto.
Ciertas clases concreta implementan esta interfaz e inyectamos a través del tipo genérico y no la implementación
concreta.
Entonces podremos tener más clases que implementan la interfaz y a través de un selector que se le llama
calificador o coali fáser, que después lo vamos a ver.
Podemos seleccionar qué implementación concreta de esa interfaz vamos a utilizar, a inyectar en el
controlador.
Pero bien, vamos por partes.
Lo primero es crear una nueva interfaz para mi servicio.
Entonces nos vamos a servis en el package.
Vamos a crear una interfaz New Interface.
Le vamos a llamar I mayúscula de interfaz, servicio y servicio y de interfaz.
Aunque también le podrían colocar el nombre que queramos, pero por convención, por estándar, los
nombres de interfaces terminan en able o ible, ya que representan comportamientos.
Por ejemplo, ejecutable imprimible conversable.
En fin, hable o ible.
Pero bueno, si tenemos una interfaz, un nombre que no pega o no calza con able oponible, como por
ejemplo cliente servidor o cliente servicio, le podemos colocar una I mayúscula antepuesta al nombre
tal como lo tenemos acá.
Finalizar entonces una interfaz contiene métodos sin implementar contratos.
Estos contratos dice qué operaciones van a implementar las clases concretas?
En el fondo ese comportamiento lo que hacen.
Entonces podríamos tener más de una clase concreta que implementa interfaz y todas hacen cierta tarea,
cierto trabajo, pero de forma distinta implementada por ejemplo de alguna u otra forma diferente.
Llevando un ejemplo en base de datos, podríamos tener una que trabaja con J de DCD con consultas nativas
SQL, mientras que otra implementación trabaje con Internet o JPA con un o RM consultas a nivel de objetos.
Acá tenemos el método Operación que rotonda un streak vamos a guardar, nos vamos a ir a mi servicio
y vamos a implementar esta interfaz.
Perfecto.
Si se fijan, funciona bien.
Ahora, qué pasa si quitamos este método?
Lo vamos a quitar automáticamente.
Te marca un error, ya que mi servicio debe implementar el método genérico o abstracto de la interfaz
operación de que está implementando.
Es un protocolo que debe cumplir un contrato, por lo tanto, está obligado siempre a implementar este
método.
Voy a volver a como lo teníamos el Loved Right, una anotación que indica que este método es una implementación
de un padre, ya sea una interfaz o una clase que estemos heredando.
Estamos o escribiendo o implementando este método vamos a guardar.
Y ahora que mi servicio implementa la interfaz, podemos inyectar a través del tipo genérico.
Nos vamos al controlador y en vez de la clase concreta usamos la interfaz.
Importamos.
Quitamos el import de la clase concreta y nuestro código está mucho mejor, mucho más desacoplar.
Ahora depende de algo genérico y no de algo concreto.
Como es genérico, la mantención es mucho más simple.
Ahora podríamos crear otra clase.
Mi servicio, mi servicio.
Otro que implementa esta misma interfaz y simplemente acá vamos a estar inyectando a través de la interfaz.
Lo que sí tendríamos que usar un calificador para indicar que implementación concreta vamos a inyectar
a través del nombre del componente, como por ejemplo los componentes.
Acá también le podemos dar un nombre, un identificador.
Por ejemplo, mi servicio, mi servicio simple por poner un nombre.
Entonces con un calificador indicamos que vamos a inyectar mis servicios simple, pero como tenemos
una sola implementación no es necesario, va a inyectar la primera que encuentre la primera implementación
concreta de esta interfaz, siempre cuando esté anotada con component o con servis.
Bien, vamos a ejecutar.
Y nos vamos a la raíz.
Se fijan y funciona igual que entran de forma transparente, pero por detrás de escena, inyectando
mediante la interfaz.
Bien.
Y antes finalizar una clase de componentes, SPRI tiene que tener ciertas características, como por
ejemplo siempre un constructor por defecto vacío.
En este caso, como no tenemos ningún constructor, va a tomar el constructor por defecto, sin parámetros,
vacío.
Pero si tenemos una clase cualquiera que es un componente spring y tiene un constructor con parámetros,
además de ese constructor, estamos obligados a tener otro constructor sin argumento vacío, ya que
es Brink por detrás de escena instancia.
Estos objetos los maneja de forma automática, pero esta instancias lo hace con el constructor sin parámetros.
Por lo tanto, si tenemos un constructor con parámetros y no implementamos un constructor por defecto
vacío, va a lanzar error de que no encuentra un constructor por defecto sin parámetros para poder crear
esta instancia y para poder manejarla.
Entonces, como característica básica, todo componente spring que vamos a registrar en el contenedor
tiene que tener un constructor por defecto sin argumento.
En este caso es implícito de que no tenemos ningún constructor.
Bien, entonces por eso es importante utilizar en la inyección de dependencia los tipos más genéricos
ojalas interfaces o clases abstracta.
De esa forma, desacople, vamos del controlador o de la clase que estemos inyectando una implementación
concreta.
Si no es algo genérico, que podría ser cualquier otro tipo concreto sin tener que modificar o intervenir
el código.
Por ahora nada más nos vemos.