¿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.
- Librería (Library): es una ‘herramienta’. Cuando la necesito, saco el martillo y lo uso, o cojo la sierra. Puedo construir la casa como yo quiera. (Ej.: React, jQuery)
- Framework: es un ‘marco’ (Frame). Es una casa piloto en la que ya están levantados los pilares y las paredes. Yo solo elijo el color del papel pintado o coloco los muebles siguiendo las reglas establecidas; no puedo arrancar los pilares a mi antojo.
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.
- Acción: voy yo mismo al supermercado a comprar un cuchillo.
Knife knife = new Knife(); - Problema: ¿y si compré un ‘cuchillo japonés’ y de repente el menú pasa a ser de cocina china y necesito un ‘cuchillo chino’? Tengo que rehacer la mano (el código) que sujeta el cuchillo. Cada vez que cambia la herramienta, el chef también se ve afectado. (Alto acoplamiento)
2. La forma de Spring (Spring manda)
Sigo siendo el chef. Pero esta vez hay un encargado de ingredientes y herramientas: el Spring Container.
- Acción: yo solo grito: «¡Un cuchillo, por favor!». Me da igual de qué marca sea.
- DI (Dependency Injection): el encargado me pone el cuchillo en la mano (Inject). Hoy puede darme un cuchillo japonés y mañana uno chino.
- Ventaja: aunque cambie el cuchillo, no tengo que tocar el código. Solo tengo que cocinar con el cuchillo que me ponen en la mano. (Bajo acoplamiento)
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.
- Con cambiar una sola línea en la configuración de Spring (Configuration), algo como «inyecta Hyundai Card», puedes cambiar el medio de pago sin que el código de
PaymentServicese toque ni en una sola línea.
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.
- Escaneo (Component Scan): Spring busca minuciosamente las clases que llevan
@Component,@Serviceo@Repository. - Registro (Bean Registration): crea exactamente un objeto (Singleton) de cada clase encontrada y lo guarda en su propio almacén (Container). A esto se le llama ‘Bean’.
- Inyección (Auto Wiring): identifica qué relaciones necesitan los objetos entre sí y los empareja.
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é?
- Inmutabilidad (Final): una vez inyectado, no se puede cambiar. Las piezas no deberían cambiar a mitad de la ejecución de la aplicación.
- Prevención de referencias circulares: detecta en cuanto arrancas el servidor el estado de ‘espera infinita’ en el que A necesita a B y B necesita a A.
- Facilidad para hacer pruebas: al escribir pruebas unitarias con código Java puro, sin Spring, puedo pasar yo mismo objetos falsos (Mock).
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.


