¿por qué usas Spring?

Ernesto Arroyo Ron
eurobits-techblog
Published in
5 min readJul 23, 2018

Hace tiempo empecé a realizar esta pregunta en entrevistas. Aunque en principio parece sencilla es sorprendente lo que se responde en perfiles que se presentan como arquitectos senior.

Mucha gente conoce las tecnologías (¡siempre aprendo algo en las entrevistas!) pero encuentro una cierta falta de fundamentos básicos de arquitectura, algo menos de herramientas y algo más de Martin Fowler, Alistair Cockburn, o Kent Beck, porque como bien sostiene Robert C. Martin, las opciones tecnológicas son y deben ser detalles de tu arquitectura. [1,2]

También es cierto que yo también tenía este lío hace tiempo, y que se arregla leyendo (mucho, me temo) así que he decidido escribir algo sobre lo que yo entiendo es la esencia de Spring.

¿Porqué o para qué usas Spring?

Of course Spring is a TM of Pivotal!

La peor de todas las respuestas para alguien que se presenta como arquitecto es, obviamente, “no lo sé”; pero también he encontrado respuestas como “es que tiene módulos y utilidades para todo” o “es mejor que los EJB”…

Una buena respuesta que viene a ser suficiente podría ser “para tener inyección de dependencias”, que si bien no es completa sí es correcta y se acerca a la esencia de Spring.

En [6] que es una excelente referencia para tener la certificación oficial de Spring encontramos el texto:

“A Java application is essentially composed of objects talking to each other. The reason why Spring has gained so much praise in Java application development is that it makes connecting and disconnecting objects easy by providing a comprehensive infrastructure support for assembling objects. Using Spring to develop a Java application is like building a lightly connected Lego castle; each object is a Lego piece that you can easily remove and replace with a different one”

Bueno, sí, la principal característica de Spring es su motor de inyección de dependencias y la gestión del ciclo de vida de los beans, pero en realidad la inyección de dependencias es un medio, no un fin.

Una buena definición de la inyección de dependencias es referida en [4]: “dependency Injection is a set of software design principles and patterns that enable us to develop loosely coupled code”.

Pero aún no contestamos a la pregunta original… porque hay otros motores con inyección de dependencias: anteriormente Picocontainer, Apache Avalon, o Google Guice; y cuidado ahora con el “New Kid on the Block”, Micronaut.

La inyección de dependencias es una forma de implementar la inversión del control.

La inversión del control es la respuesta

Confundir la inversión del control con la inyección de dependencias es fácil, incluso buscando mucho en la red encuentras confusión y explicaciones no siempre acertadas.

Aunque como digo la diferencia es sutil creo que es bueno ponerse académico y estricto:

El principio de inversión del control dicta lo siguiente:

  • High level modules should not depend upon low level modules. Both should depend upon abstractions.
  • Abstractions should not depend upon details. Details should depend upon abstractions

Y la mejor forma de entenderlo es con un ejemplo (*)

Un ejemplo de un diseño incorrecto, donde existe acoplamiento, vendría a ser el siguiente:

public class Sender {  private Receiver receiver = new SomeReceiver();}
Diseño acopado (erróneo)

Y aunque creas que usas un interfaz (Receiver) en realidad si usas un diagrama de clases verás que el control viene desde el objeto de alto nivel (Sender) porque es el que se responsabiliza de contruir el objeto receptor.

En cambio cuando llegas a la inversión del control la flecha (que representa quién conoce a quién) es totalmente al contrario.

package sender;
/**
* A client for some service
*/
public class Sender { private Receiver receiver; // Here it is! The injection!!
public Sender(@Autowired Receiver r) {
receiver = r;
}
// This is the business logic
public void doSomething() {
receiver.receiveThis();
}
// The interface belongs to the caller!
// We know nothing about the implementation!
public interface Receiver {
void receiveThis();
}
}----package receiver;import sender.Sender;public class SpecificReceiver implements Sender.Receiver { public void receiveThis() {
//do something interesting
}
}----package configuration;@Configuration
public class SenderConfiguration {
@Conditional... // spring features!!
@Bean public Sender.Receiver receiver() {
return new SpecificReceiver();
}
}

(*) este ejemplo no tiene mucho de original, de hecho lo he tomado de Robert C. Martin con una poco original aportación con la configuración de Spring.

Ahora hemos invertido el control porque el objeto cliente no controla la existencia del objeto servidor. Y claro, para montar todo el puzzle debe existir algo que nos hará llegar la implementación concreta necesaria: que nos la inyecte.

Observa que, además, el objeto cliente es el dueño del contrato (el interfaz) y esto es importante: sólo invoco lo que necesito (Interface Segregation Principle) y se desacopla totalmente el diseño.

Es esta la razón de ser y la esencia de Spring: una herramienta para invertir el control; un diseño sin acoplamiento que permite los test, el mantenimiento, y la extensión del mismo.

Y además Spring es cool porque…

Ahora que he presentado la esencia es más fácil vender sus ventajas: esa inyección de dependencias es posible por decenas de medios (anotaciones, javaconfig, XML,…) y tienes opciones hasta aburrirte y más aún con la llegada de Spring Boot y su forma de instanciar los beans dependiendo del entorno (con cosas como la familia de @ConditionalOn…)

Not this architecture,… ;o)

Spring es el estandar de facto (en Java) como motor de inyección de dependencias y de gestión del ciclo de vida de los objetos (beans), y además a través de su modo de “ensamblar las piezas” ha construido un potente ecosistema de librerías y herramientas que nos facilita montar nuestras aplicaciones de una forma común y conocida, con un modelo de bajo acoplamiento en nuestras clases.

Referencias

  1. Robert C. Martin, Clean Architecture, Prentice-Hall.
  2. Robert C. Martin Blog: A Little Architecture.
  3. Martin Fowler: Inversion of Control Containers and the DI Pattern
  4. http://www.jeremybytes.com/downloads/dependencyinjection.pdf
  5. https://www.manning.com/books/dependency-injection
  6. Iuliana Cosmina, Pivotal Certified Spring Web Application Developer Exam, Apress.

--

--