¿Corea del Sur es una «república Spring»?
Si quieres conseguir trabajo como desarrollador backend en Corea, hay una pregunta de la que es difícil escapar: «¿Sabes usar Spring?»
Si entras en los portales de empleo, nueve de cada diez ofertas especifican «experiencia con Spring Boot» como requisito. No por nada existe incluso la expresión «república Spring». Cuando estaba en la universidad, yo pensaba que aquello no era más que una moda.
«Si se puede programar directamente en Java, ¿por qué usar Spring, que es tan pesado?» «¿No es más fácil Node.js o Python (Django)?»
Pero al entrar en el mundo real y pasar por proyectos grandes, entendí la razón. Spring no era una moda pasajera, sino una mesa de trabajo estándar que incontables desarrolladores veteranos habían ido puliendo para construir sistemas empresariales enormes y complejos de forma segura y rápida.
Esta serie trata justamente de cómo levantar un castillo que no se derrumbe, un Monolith, sobre esa mesa de trabajo estándar.
Framework: por qué no puedes hacerlo todo a tu manera
Antes de entrar de lleno en la parte técnica, hay algo que conviene aclarar. ¿Qué es exactamente un framework? ¿Y en qué se diferencia de una librería?
Ya lo mencioné brevemente en la serie Re: Booting, pero la diferencia decisiva entre ambos está en una sola cuestión: quién tiene el control.
Spring es un framework. Por eso, usar Spring se parece bastante a firmar una promesa: «voy a dejar un poco de lado mi estilo de programar y haré las cosas como Spring manda». El núcleo de ese «hacerlo como Spring manda» es justamente la Inversión de Control (IoC), de la que hablaremos hoy.
«Por favor, dejen de usar tanto new«
La primera regla de esa promesa fue impactante. Básicamente decía: no uses el operador new, uno de los fundamentos más básicos de Java.
En la universidad, si necesitaba un objeto, lo natural era escribir MemberService service = new MemberService();. Si necesitaba algo, lo creaba yo mismo y lo usaba. ¿Qué podía haber más lógico?
Pero después de entrar a trabajar y abrir un proyecto de Spring Boot, no encontraba la palabra clave new por ninguna parte. En su lugar había anotaciones extrañas como @Autowired o @RequiredArgsConstructor.
«A ver, si nadie crea el objeto, ¿cómo se está llamando al método? ¿De verdad esto funciona?»
Cuando se lo pregunté a un desarrollador senior, la respuesta sonó frustrantemente ambigua. «El Spring Container te lo inyecta solo, así que no hace falta crearlo manualmente. De hecho, si usas new directamente, luego será mucho más difícil mantener el código.»
No lo entendía. Si yo era el dueño del código que escribía, ¿por qué no podía ni siquiera crear un objeto libremente? Me parecía casi una dictadura de Spring.

El chef y el encargado de los ingredientes (IoC & DI)
Para entender por qué hace falta esta regla que parece tan autoritaria, cambiemos nuestra metáfora y vayamos a la cocina de un restaurante.
1. La forma tradicional (yo mando)
Yo soy un chef, una Class. Para cocinar, necesito un cuchillo, una Dependency.
2. La forma de Spring (Spring manda)
Sigo siendo el chef. Pero esta vez hay un encargado de ingredientes y herramientas: el Spring Container.
En otras palabras, en lugar de gestionar yo mismo los recursos que necesito, alguien externo los gestiona y me los entrega. Eso es la Inversión de Control (IoC: Inversion of Control), y la técnica concreta para hacerlo es la Inyección de Dependencias (DI).

[Code Verification] ¿Por qué es peligroso new?
Solo con palabras no termina de sentirse. Vamos a compararlo directamente con código. Supongamos que estamos construyendo un sistema de pagos con tarjeta.
1. Mal ejemplo: creación directa (alto acoplamiento)
public class PaymentService {
// Elegi y cree directamente una Samsung Card (usando new)
private final SamsungCard card = new SamsungCard();
public void pay() {
card.payment(); // Solo se puede pagar con Samsung Card
}
}
El problema: un día el jefe dice: «¡Pasémonos a Hyundai Card, que tiene comisiones más bajas!» Entonces yo tendría que abrir el código de PaymentService y reemplazar cada SamsungCard por HyundaiCard. ¿Y si ese código está en cien sitios distintos? Horas extra aseguradas.
2. Buen ejemplo: inyección de dependencias (bajo acoplamiento)
public class PaymentService {
private final Card card; // No especificar una emisora concreta (usar la interfaz)
// Inyeccion por constructor: confias en que alguien de fuera te pasara la tarjeta
public PaymentService(Card card) {
this.card = card;
}
public void pay() {
card.payment();
}
}
Ahora a PaymentService le da igual qué implementación concreta de tarjeta reciba.
Ese es el núcleo de lo que en el trabajo se llama «código fácil de mantener» o principio OCP. Y justamente esa flexibilidad es la razón por la que se usa Spring Boot.
Spring Container: un hotel para objetos
Entonces, ¿quién es exactamente ese «encargado» que crea objetos y los reparte? Precisamente eso es el Spring Container.
En el momento en que arrancamos el servidor de Spring Boot con run, por dentro están ocurriendo muchísimas cosas.
Nuestro trabajo consiste únicamente en pegar una etiqueta a la clase que diga algo como «por favor, gestiona esto», usando por ejemplo @Service. El resto lo hace Spring, como el gerente de un gran hotel que organiza a todos los huéspedes.
Consejo práctico: usa inyección por constructor
Spring ofrece varias formas de inyectar dependencias: inyección de campos con @Autowired, inyección por setter o inyección por constructor. Pero en proyectos reales casi siempre se recomienda la inyección por constructor. Es el patrón que normalmente se usa con @RequiredArgsConstructor de Lombok.
@Service
@RequiredArgsConstructor // Esto genera automaticamente la inyeccion por constructor.
public class OrderService {
// se puede usar final, por lo que es seguro
private final PaymentService paymentService;
}
¿Por qué?
Cierre: no es un mago, sino un director de orquesta
Al principio, Spring me generaba rechazo porque sentía que hacía lo que quería con mi código. Pero ahora lo veo de otra manera. Spring no es un dictador que me complica la vida, sino un director de orquesta competente que ordena relaciones complejas entre objetos.
Gracias a eso, paso menos tiempo pensando «¿qué objeto tengo que crear?» y puedo concentrarme más en «¿cómo construyo la lógica de negocio con este objeto?». Probablemente por eso tantos desarrolladores en Corea siguen tan volcados con Spring.
Ahora ya le hemos entregado a Spring el control sobre los objetos. El servidor está listo para arrancar. Pero una aplicación web no funciona sola: tiene que hablar con el frontend. En la época de PHP era cómodo porque HTML y código convivían en un mismo archivo. Entonces, ¿por qué hoy se separa el frontend, Vue o React, del backend? ¿Y por qué aparece un error rojo de CORS en cuanto intentas conectar ambas partes?
En la próxima entrega veremos el cambio en la arquitectura web, SSR vs CSR, y la verdadera identidad de CORS, la barrera que se interpone entre ambos.