Si ya programas en Java, probablemente hayas oído hablar de Spring como "el framework que usa todo el mundo en el mundo empresarial". Y probablemente también hayas oído la queja histórica que lo acompañaba: que configurarlo era una tarea larga, repetitiva y llena de ficheros XML. Spring Boot nació exactamente para eliminar ese dolor. Esta lección explica qué problema concreto resuelve Spring Boot, cómo lo resuelve mediante cuatro mecanismos muy identificables, y cómo encaja dentro del ecosistema Spring. Al final conocerás también CicloUrbana, la aplicación real que construirás paso a paso durante todo el curso y que dará sentido práctico a cada concepto.
Contenido
- Spring Framework: el punto de partida
- El "infierno de configuración": un ejemplo comparativo real
- Los cuatro pilares de Spring Boot
- Spring Boot dentro del ecosistema Spring
- Qué tipo de aplicaciones se construyen con Spring Boot
- El proyecto del curso: CicloUrbana
- Versiones de Spring Boot 3.x y requisitos de Java
- Errores Comunes y Consejos
- Ejercicios
- Spring Framework: el punto de partida
Antes de entender Spring Boot hay que entender qué es Spring Framework, porque Spring Boot no lo sustituye: lo envuelve.
Spring Framework apareció en 2003 con una idea central: el contenedor de inversión de control (IoC, Inversion of Control). En lugar de que cada clase cree con new los objetos que necesita, es el framework quien crea esos objetos —llamados beans— y se los entrega a quien los pide. A eso se le llama inyección de dependencias.
La ventaja es inmediata:
- Las clases dependen de interfaces, no de implementaciones concretas.
- El código es fácil de probar, porque en una prueba puedes inyectar una implementación falsa.
- La configuración de "qué se conecta con qué" vive en un solo sitio y no repartida por todo el código.
Sobre ese núcleo, Spring fue añadiendo módulos: acceso a datos, transacciones, MVC para web, seguridad, mensajería... Todo excelente. El problema no era la potencia, sino el coste de arrancar.
- El "infierno de configuración": un ejemplo comparativo real
Hasta aproximadamente 2014, poner en marcha una aplicación web Spring que expusiera un endpoint HTTP y hablara con una base de datos exigía este trabajo previo:
- Crear un proyecto Maven y elegir a mano la versión de cada librería (Spring Core, Spring MVC, Spring JDBC, Jackson, un pool de conexiones, el driver JDBC...), rezando para que fueran compatibles entre sí.
- Escribir un
web.xmlpara registrar el servlet de Spring. - Escribir uno o varios ficheros XML de contexto declarando los beans.
- Empaquetar un fichero WAR y desplegarlo en un servidor de aplicaciones instalado aparte (Tomcat, JBoss, WebLogic).
Veamos cómo se declaraba algo tan básico como un origen de datos y un gestor de transacciones en el estilo clásico:
<!-- applicationContext.xml — configuración clásica de Spring (estilo antiguo) -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="...">
<!-- 1. Hay que declarar el pool de conexiones a mano -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/ciclourbana"/>
<property name="username" value="ciclo"/>
<property name="password" value="secreto"/>
<property name="maxTotal" value="20"/>
</bean>
<!-- 2. Hay que declarar el gestor de transacciones y enlazarlo al dataSource -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 3. Hay que activar explícitamente el soporte de @Transactional -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 4. Y decirle a Spring dónde buscar tus clases -->
<context:component-scan base-package="com.ciclourbana"/>
</beans>Y además un web.xml para arrancar todo eso dentro del servidor:
<!-- web.xml — necesario para que el servidor de aplicaciones cargue Spring -->
<web-app>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>Son unas 40 líneas de configuración que no aportan ninguna funcionalidad de negocio: no hay ni una estación de bicicletas ni un alquiler. Es puro andamiaje. Y hay que repetirlo, con matices, en cada proyecto nuevo.
Lo mismo con Spring Boot
Con Spring Boot, ese bloque entero se reduce a un fichero de propiedades y una clase de arranque:
# src/main/resources/application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/ciclourbana
spring.datasource.username=ciclo
spring.datasource.password=secretopackage com.ciclourbana;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CicloUrbanaApplication {
public static void main(String[] args) {
SpringApplication.run(CicloUrbanaApplication.class, args);
}
}Explicación de lo que acaba de ocurrir:
- Spring Boot detecta que hay un driver de PostgreSQL en el classpath y que existe una propiedad
spring.datasource.url. Con eso crea elDataSourcepor ti, usando HikariCP como pool de conexiones. - Detecta también que hay un
DataSourcey crea el gestor de transacciones, y activa el soporte de@Transactional. - El
component-scanse activa solo, tomando como raíz el paquete donde está la clase anotada con@SpringBootApplication(com.ciclourbana). - No hace falta
web.xmlporque no hay servidor externo: el servidor viene dentro de la aplicación.
La comparación resumida:
| Aspecto | Spring clásico (pre-Boot) | Spring Boot |
|---|---|---|
| Versiones de librerías | Elegidas y cuadradas a mano | Gestionadas por el parent / BOM |
| Configuración de infraestructura | XML o @Configuration extensos |
Autoconfiguración + propiedades |
| Servidor web | Externo, instalado aparte | Embebido en el JAR |
| Artefacto de despliegue | WAR desplegado en un contenedor | JAR ejecutable (java -jar) |
| Tiempo hasta el primer endpoint | Horas | Minutos |
| Métricas, salud, logs | Se añaden a mano | Actuator, listo para producción |
Idea clave: Spring Boot no es un framework nuevo que compita con Spring. Es una capa de opinión y automatización sobre Spring Framework. Todo lo que sabes de Spring sigue siendo válido; simplemente dejas de escribir la parte aburrida.
- Los cuatro pilares de Spring Boot
Casi todo lo que hace Spring Boot se explica con cuatro mecanismos. Conviene tenerlos claros desde el primer día porque los verás una y otra vez.
3.1 Autoconfiguración
Spring Boot mira qué hay en el classpath y qué has configurado, y a partir de ahí registra automáticamente los beans que normalmente harían falta. Si encuentra la librería de Spring MVC, configura un DispatcherServlet. Si encuentra un driver JDBC y una URL, configura un DataSource.
La regla de oro es que la autoconfiguración es condicional y cede el paso: si tú defines tu propio bean, Spring Boot se aparta y usa el tuyo. Nunca te bloquea. El mecanismo interno (las anotaciones @Conditional...) se estudia en detalle en el módulo 2, lección 02-06.
3.2 Starters
Un starter es una dependencia Maven que no contiene código, sino una lista curada de dependencias que funcionan bien juntas. En lugar de añadir ocho librerías con sus versiones, añades una:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>Esa única línea arrastra Spring MVC, Jackson (para JSON), la validación, el registro de logs y un Tomcat embebido, todos en versiones compatibles entre sí. Observa que no hay etiqueta <version>: la versión la decide el parent de Spring Boot. Los starters se detallan en la lección 01-04 y su funcionamiento interno en la 02-06.
3.3 Servidor web embebido
Una aplicación Spring Boot web contiene su propio servidor. Al ejecutar java -jar ciclourbana.jar se arranca un Tomcat (o Jetty, o Undertow) dentro del mismo proceso Java.
Las consecuencias son grandes:
- El artefacto es autocontenido: un solo fichero JAR con todo dentro.
- La aplicación se ejecuta igual en tu portátil que en producción.
- Encaja de forma natural con contenedores Docker y con plataformas cloud, donde el modelo es "un proceso, un puerto".
- Ya no existe la clase de error "en mi máquina funciona, pero el Tomcat del servidor tiene otra versión".
3.4 Características listas para producción
Spring Boot incluye, con una sola dependencia (Actuator), lo que una aplicación necesita para vivir en producción:
- Endpoints de salud (
/actuator/health) que un balanceador o Kubernetes pueden consultar. - Métricas (memoria, peticiones por segundo, latencias) exportables a Prometheus.
- Información de la aplicación, volcado de la configuración efectiva, cambio de nivel de log en caliente.
Todo esto se trata en los módulos 7 y 9. Menciono aquí solo que existe, porque es uno de los cuatro pilares y explica por qué Spring Boot es el estándar de facto en empresa.
- Spring Boot dentro del ecosistema Spring
"Spring" es una familia de proyectos. Esta tabla sitúa cada pieza y te dice en qué módulo del curso aparecerá:
| Proyecto | Qué aporta | ¿Cuándo lo usarás en CicloUrbana? |
|---|---|---|
| Spring Framework | Núcleo: contenedor IoC, inyección de dependencias, AOP, transacciones, Spring MVC | Módulos 2 y 3 |
| Spring Boot | Autoconfiguración, starters, servidor embebido, Actuator | Todo el curso |
| Spring Data JPA | Repositorios automáticos sobre bases de datos relacionales | Módulo 4 |
| Spring Security | Autenticación, autorización, protección de la API, JWT | Módulo 5 |
| Spring Test | Utilidades de prueba integradas con JUnit y Mockito | Módulo 6 |
| Spring Cloud | Configuración distribuida, descubrimiento de servicios, tolerancia a fallos | Módulo 7 (introducción) |
| Spring Batch / Integration | Procesos por lotes e integración de sistemas | Fuera del alcance del curso |
Piensa en Spring Boot como el integrador: no reimplementa Spring Data ni Spring Security, sino que los autoconfigura para que funcionen nada más añadir su starter.
- Qué tipo de aplicaciones se construyen con Spring Boot
Spring Boot no está limitado a APIs REST, aunque sea su uso más habitual:
- APIs REST y backends de aplicaciones web o móviles. Es el caso mayoritario y el que sigue este curso.
- Microservicios. Cada servicio es un JAR autónomo con su puerto y su base de datos.
- Aplicaciones web tradicionales con vistas en servidor (Thymeleaf, FreeMarker).
- Aplicaciones de línea de comandos y procesos por lotes, sin servidor web, usando
CommandLineRunner(lección 01-05). - Consumidores de mensajería (Kafka, RabbitMQ) o tareas programadas (módulo 7).
- APIs GraphQL o servicios reactivos con Spring WebFlux, para cargas de altísima concurrencia.
- El proyecto del curso: CicloUrbana
Durante todo el curso construirás CicloUrbana, la plataforma de gestión de la red municipal de bicicletas eléctricas de Ribalta, una ciudad ficticia de tamaño medio.
El contexto de negocio
El ayuntamiento de Ribalta ha instalado estaciones de anclaje repartidas por la ciudad —"Plaza Mayor", "Estación Norte", "Parque del Río" y "Universidad", entre otras—. Cada estación tiene una capacidad limitada de anclajes y unas coordenadas geográficas. En ellas hay bicicletas eléctricas identificadas por matrículas del tipo RB-0142, cada una con un nivel de batería y un estado.
Un usuario registrado desbloquea una bicicleta en una estación, circula y la devuelve en otra estación. Ese trayecto es un alquiler, que se cobra según una tarifa. Si algo va mal —freno roto, batería que no carga—, se abre una incidencia.
Los actores
| Actor | Qué hace en el sistema |
|---|---|
| Ciudadano usuario | Consulta estaciones y bicicletas disponibles, inicia y finaliza alquileres, ve su historial |
| Operario de mantenimiento | Recibe incidencias, cambia el estado de las bicicletas, reequilibra estaciones |
| Gestor municipal | Consulta estadísticas de uso, gestiona tarifas, da de alta estaciones |
| Sistema externo | La app móvil y los paneles informativos de las estaciones consumen la API |
La API que acabará existiendo
Al terminar el curso, CicloUrbana expondrá una API REST versionada bajo /api/v1. Un adelanto de su forma final:
| Método y ruta | Propósito |
|---|---|
GET /api/v1/estaciones |
Listar estaciones, con filtros y paginación |
GET /api/v1/estaciones/{id} |
Detalle de una estación |
POST /api/v1/estaciones |
Alta de estación (solo gestor) |
GET /api/v1/estaciones/{id}/bicicletas |
Bicicletas disponibles en una estación |
POST /api/v1/alquileres |
Iniciar un alquiler |
POST /api/v1/alquileres/{id}/finalizar |
Devolver la bicicleta y calcular el importe |
POST /api/v1/incidencias |
Reportar una avería |
POST /api/v1/auth/login |
Obtener un token JWT |
La arquitectura objetivo
flowchart TD
subgraph Clientes
A["App móvil"]
B["Panel de estación"]
C["Backoffice municipal"]
end
A --> API
B --> API
C --> API
subgraph "CicloUrbana (Spring Boot)"
API["Capa web<br/>Controladores REST /api/v1"]
SEC["Spring Security<br/>JWT + roles"]
SRV["Capa de servicio<br/>Reglas de negocio"]
REP["Spring Data JPA<br/>Repositorios"]
ACT["Actuator<br/>salud y métricas"]
API --> SEC
SEC --> SRV
SRV --> REP
end
REP --> DB[("PostgreSQL")]
ACT --> MON["Prometheus / Grafana"]
No te preocupes si algunas cajas te resultan desconocidas: cada una corresponde a un módulo del curso. En el módulo 1 solo construirás la capa web con datos fijos en memoria; el resto llegará a su debido tiempo.
Convenciones del proyecto
Estas decisiones se mantendrán invariables durante todo el curso:
| Elemento | Valor |
|---|---|
groupId |
com.ciclourbana |
artifactId |
ciclourbana |
| Paquete base | com.ciclourbana |
| Java | 21 (LTS) |
| Spring Boot | 3.x |
| Construcción | Maven, con wrapper mvnw |
| Prefijo de la API | /api/v1 |
| Idioma del código | Identificadores y comentarios en español |
- Versiones de Spring Boot 3.x y requisitos de Java
Spring Boot 3 supuso una ruptura importante respecto a la rama 2.x:
- Requiere Java 17 como mínimo. Este curso usa Java 21, la versión LTS recomendada, que aporta records, pattern matching y hilos virtuales.
- Migración de
javax.*ajakarta.*. Las anotaciones de persistencia y validación pasaron dejavax.persistenceajakarta.persistence. Si copias código antiguo de internet y vesjavax, está desactualizado. - Se apoya en Spring Framework 6, con soporte nativo para observabilidad (Micrometer) y para compilación nativa con GraalVM.
| Rama | Java mínimo | Espacio de nombres | Situación |
|---|---|---|---|
| Spring Boot 2.7 | Java 8 | javax.* |
Fin de soporte gratuito |
| Spring Boot 3.0–3.2 | Java 17 | jakarta.* |
Ramas antiguas de la línea 3 |
| Spring Boot 3.3/3.4/3.5 | Java 17 (recomendado 21) | jakarta.* |
Ramas en uso en el curso |
Un detalle práctico: Spring Boot publica versiones menores con frecuencia. Cuando generes el proyecto en la lección 01-03, Spring Initializr te ofrecerá la última estable de la rama 3.x. Acepta la que te proponga; todo lo que aprendas aquí es válido en cualquier 3.x.
Errores Comunes y Consejos
- Creer que Spring Boot sustituye a Spring Framework. No lo hace. Cuando depures un problema, recuerda que por debajo hay un
ApplicationContextde Spring Framework de toda la vida. Aprender el núcleo (módulo 2) es lo que te permitirá salir de los atascos. - Pensar que la autoconfiguración es magia incontrolable. Es código Java normal, condicional y perfectamente inspeccionable. Cualquier bean que definas tú tiene prioridad sobre el autoconfigurado.
- Seguir tutoriales de Spring Boot 2 sin darse cuenta. Señales de alerta: importaciones
javax.persistence,WebSecurityConfigurerAdapter,antMatchers(). Todo eso ha desaparecido o cambiado en la rama 3. - Añadir dependencias con versión explícita. Si el starter la gestiona, no la fijes tú: romperás la compatibilidad que el parent garantiza.
- Consejo: acostúmbrate desde hoy a consultar la documentación oficial en
docs.spring.io. Está organizada por versión y es de las mejores del ecosistema Java.
Ejercicios
Ejercicio 1
Enumera las cuatro tareas de infraestructura que un desarrollador debía hacer a mano en Spring clásico y explica, para cada una, qué pilar de Spring Boot la elimina.
Ejercicio 2
Un compañero te dice: "He añadido spring-boot-starter-web pero quiero usar Jetty en lugar de Tomcat. Con Spring Boot eso ya no se puede elegir." Razona por qué esa afirmación es incorrecta, apoyándote en la idea de que la autoconfiguración "cede el paso".
Ejercicio 3
Diseña, sin escribir código, las rutas REST que necesitaría el operario de mantenimiento de CicloUrbana para hacer su trabajo. Indica método HTTP y ruta bajo /api/v1, y justifica brevemente cada una.
Soluciones
Solución 1
| Tarea manual en Spring clásico | Pilar que la elimina | Cómo |
|---|---|---|
| Elegir y cuadrar versiones de librerías | Starters | Una sola dependencia arrastra un conjunto compatible; la versión la fija el parent |
Declarar beans de infraestructura (DataSource, TransactionManager, DispatcherServlet) en XML |
Autoconfiguración | Spring Boot los crea al detectar librerías y propiedades |
| Instalar y configurar un servidor de aplicaciones externo y empaquetar un WAR | Servidor embebido | El servidor va dentro del JAR ejecutable |
| Añadir a mano métricas, comprobaciones de salud y gestión de logs | Características listas para producción | Actuator las expone con una sola dependencia |
Solución 2
La afirmación es incorrecta. spring-boot-starter-web incluye Tomcat por defecto, pero es una decisión reversible: basta con excluir el starter de Tomcat y añadir el de Jetty.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Quitamos el servidor por defecto -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Y ponemos el que queremos -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>Al desaparecer Tomcat del classpath, la autoconfiguración que lo activaba deja de cumplirse y se activa la de Jetty. Este es exactamente el principio de "opinión por defecto, decisión reversible": Spring Boot elige por ti, pero nunca te ata.
Solución 3
Una propuesta razonable para el operario de mantenimiento:
| Método y ruta | Justificación |
|---|---|
GET /api/v1/incidencias?estado=ABIERTA |
Ver su cola de trabajo pendiente; el filtro por estado evita traer histórico innecesario |
GET /api/v1/incidencias/{id} |
Consultar el detalle de una avería concreta antes de desplazarse |
PATCH /api/v1/bicicletas/{matricula} |
Cambiar el estado de una bicicleta (por ejemplo a MANTENIMIENTO); PATCH porque es una modificación parcial |
POST /api/v1/incidencias/{id}/resolver |
Marcar la incidencia como resuelta; se modela como acción porque dispara lógica de negocio, no es un simple cambio de campo |
GET /api/v1/estaciones?ocupacion=ALTA |
Detectar estaciones saturadas o vacías para reequilibrar bicicletas |
Nota: POST /api/v1/incidencias/{id}/resolver rompe deliberadamente la ortodoxia REST más purista. Es un compromiso muy habitual y lo discutiremos con detalle en el módulo 3.
Conclusión
Spring Boot es una capa de automatización sobre Spring Framework que elimina la configuración repetitiva mediante cuatro pilares: autoconfiguración, starters, servidor embebido y características listas para producción. No reemplaza a Spring: lo hace productivo desde el minuto uno, sin quitarte el control, porque cualquier decisión automática puede sobrescribirse.
También conoces ya CicloUrbana, la red de bicicletas eléctricas de Ribalta que construirás capa a capa: primero la web con datos en memoria, después la persistencia, la seguridad, las pruebas y finalmente el despliegue y la monitorización.
En la siguiente lección, Configuración de tu Entorno de Desarrollo, prepararás la máquina: instalarás el JDK 21, entenderás por qué el curso usa Maven, elegirás IDE y herramientas de prueba de APIs, y validarás todo con un checklist antes de escribir la primera línea de CicloUrbana.
Curso de Spring Boot
Módulo 1: Introducción a Spring Boot
- ¿Qué es Spring Boot?
- Configuración de tu Entorno de Desarrollo
- Creando tu Primera Aplicación Spring Boot
- Entendiendo la Estructura del Proyecto
- El Arranque y el Ciclo de Vida de la Aplicación
Módulo 2: Conceptos Básicos de Spring Boot
- Anotaciones de Spring Boot
- Inyección de Dependencias en Spring Boot
- Ámbito y Ciclo de Vida de los Beans
- Configuración de Spring Boot
- Propiedades de Spring Boot
- Autoconfiguración y Starters por Dentro
Módulo 3: Construyendo Servicios Web RESTful
- Introducción a los Servicios Web RESTful
- Creando Controladores REST
- Manejo de Métodos HTTP
- Validación de Datos de Entrada
- DTOs y Mapeo entre Capas
- Manejo de Excepciones en REST
- Documentar la API con OpenAPI
Módulo 4: Acceso a Datos con Spring Boot
- Introducción a Spring Data JPA
- Configuración de Fuentes de Datos
- Creación de Entidades JPA
- Relaciones entre Entidades
- Uso de Repositorios de Spring Data
- Métodos de Consulta en Spring Data JPA
- Transacciones y Gestión de la Persistencia
- Migraciones de Esquema con Flyway
Módulo 5: Seguridad en Spring Boot
- Introducción a Spring Security
- Configuración de Spring Security
- Autenticación y Autorización de Usuarios
- Implementación de Autenticación JWT
- Seguridad a Nivel de Método y Endurecimiento de la API
Módulo 6: Pruebas en Spring Boot
- Introducción a las Pruebas
- Pruebas Unitarias con JUnit
- Simulación con Mockito
- Pruebas de Integración
- Pruebas con Testcontainers
Módulo 7: Funciones Avanzadas de Spring Boot
- Spring Boot Actuator
- Perfiles de Spring Boot
- Tareas Programadas y Ejecución Asíncrona
- Spring Boot con Docker
- Spring Boot y Microservicios
- Comunicación entre Servicios y Tolerancia a Fallos
Módulo 8: Despliegue de Aplicaciones Spring Boot
- Introducción al Despliegue
- Desplegando en Heroku
- Desplegando en AWS
- Desplegando en Kubernetes
- Integración y Entrega Continua
Módulo 9: Rendimiento y Monitoreo
- Ajuste de Rendimiento
- Caché con Spring Cache
- Monitoreo con Spring Boot Actuator
- Uso de Prometheus y Grafana
- Gestión de Registros y Logs
- Trazabilidad Distribuida
