Guía de Introducción a Spring Boot: Cocinando Aplicaciones con un Chef Java
Aprende a desarrollar aplicaciones Java de forma ágil y eficiente con Spring Boot, el framework que automatiza configuraciones y acelera tu desarrollo.
Introducción: Nuestro Chef de Cocina Java
Preparación automática
Prepara automáticamente los ingredientes (dependencias).
Configuración perfecta
Ajusta el horno a la temperatura justa (configuración automática).
Desarrollo ágil
Sirve platos rápidamente (desarrollo ágil).
Recetas reutilizables
Y nos da recetas reutilizables (anotaciones y convenciones).
Imaginemos que Spring Boot es como un chef experto que nos guía para preparar platos sofisticados (aplicaciones Java), sin que tengamos que preocuparnos por todos los ingredientes técnicos o técnicas complicadas.
¿Cómo iniciamos un nuevo proyecto?
Tres formas de preparar nuestro entorno de cocina Spring Boot:
Spring Initializr (la cocina asistida)
Acceder a https://start.spring.io y seleccionar:
  • Grupo: com.ejemplo
  • Artefacto: demo
  • Dependencias: Spring Web, Spring Boot DevTools, Lombok
Descargar el proyecto .zip, descomprimir e importar en el IDE.
Línea de comandos
curl https://start.spring.io/starter.zip -d dependencies=web,devtools,lombok -d name=demo -d type=maven-project -d language=java -o demo.zip
Desde el IDE
IDE como IntelliJ IDEA o Spring Tool Suite permiten crear proyectos Spring Boot con asistentes.
Las anotaciones más importantes: Ingredientes secretos
Primer plato: Hola Mundo Web (con vista HTML)
Controlador
@Controller public class HolaMundoController { @GetMapping("/") public String saludar(Model model) { model.addAttribute("mensaje", "¡Hola mundo desde Spring Boot!"); return "hola"; } }
Plantilla HTML
<!DOCTYPE html> <html> <head> <title>Hola</title> </head> <body> <h1 th:text="${mensaje}">Mensaje de prueba</h1> </body> </html>
Plantilla hola.html en src/main/resources/templates/
Dependencia necesaria en pom.xml:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
Segundo plato: Hola Mundo REST (API simple)

Escribir el controlador
Crear una clase con la anotación @RestController

Definir el endpoint
Usar @GetMapping para especificar la ruta

Retornar respuesta
Spring convertirá automáticamente a JSON
@RestController public class HolaMundoRestController { @GetMapping("/api/hola") public String saludar() { return "¡Hola mundo desde una API REST!"; } }
Las anotaciones más importantes: Ingredientes secretos
¿Qué es @Autowired y para qué sirve?
La anotación @Autowired es uno de los ingredientes principales en la cocina de Spring. Permite inyectar automáticamente dependencias en nuestros componentes, es decir, pedirle al chef que nos traiga los objetos que necesitamos sin tener que crearlos manualmente.
¿Dónde y cuándo usarla?
Se puede aplicar en:
  • Atributos de clase
  • Constructores (preferido)
  • Métodos setter
Se debe usar cuando una clase necesita otra clase para funcionar. En lugar de instanciarla con new, dejamos que Spring se encargue de proporcionarla desde el contenedor.
Ejemplo detallado
Supongamos que tenemos un servicio que prepara platos:
@Service public class CocinaService { public String preparar(String nombre) { return "Plato preparado para " + nombre; } }
Y un controlador que necesita ese servicio:
@RestController public class RestauranteController { private final CocinaService cocinaService; @Autowired // Spring inyecta automáticamente la instancia de CocinaService public RestauranteController(CocinaService cocinaService) { this.cocinaService = cocinaService; } @GetMapping("/api/ordenar/{nombre}") public String ordenar(@PathVariable String nombre) { return cocinaService.preparar(nombre); } }
Spring detecta que RestauranteController necesita una instancia de CocinaService, la busca entre los componentes disponibles (@Service, @Component, @Repository) y la inyecta automáticamente.
Este patrón se conoce como Inyección de Dependencias, y permite un código más limpio, mantenible y fácil de probar.
Autowired con un sólo constructor
En versiones modernas de Spring (a partir de Spring 4.3), la anotación @Autowired ya no es necesaria en constructores si la clase tiene un único constructor. Spring la detecta automáticamente.
@Autowired public HomeController(MensajeService mensajeService) { this.mensajeService = mensajeService; } // Unnecessary `@Autowired` annotationvscode-spring-boot(JAVA_AUTOWIRED_CONSTRUCTOR) org.springframework.beans.factory.annotation.Autowired
Ingredientes Personalizados: Controladores con Parámetros
Parámetros en la URL
@RequestParam permite capturar parámetros de consulta
@RestController public class ChefRestController { @GetMapping("/api/saludo") public String saludar(@RequestParam String nombre) { return "Hola, " + nombre + "! Bienvenido a la cocina de Spring Boot."; } }
Parámetros en la ruta (path variables)
@PathVariable captura segmentos de la URL
@RestController public class PlatoDelDiaController { @GetMapping("/api/plato/{nombre}") public String platoDelDia(@PathVariable String nombre) { return "El plato del día para " + nombre + " es: Pasta al pesto."; } }
Dividiendo tareas en la cocina: Servicios

Controlador
Recibe peticiones y devuelve respuestas
Servicio
Contiene la lógica de negocio
Repositorio
Accede a los datos
Crear un Servicio:
@Service public class CocinaService { public String prepararPlato(String nombre) { return "Plato preparado especialmente para " + nombre; } }
Inyectar el Servicio en el Controlador:
@RestController public class CocinaController { private final CocinaService cocinaService; @Autowired public CocinaController(CocinaService cocinaService) { this.cocinaService = cocinaService; } @GetMapping("/api/preparar/{nombre}") public String preparar(@PathVariable String nombre) { return cocinaService.prepararPlato(nombre); } }
Menú completo: CRUD básico con receta de cursos
Empezando con el Modelo
Clase Curso (Modelo)
@Entity public class Curso { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nombre; private String descripcion; // Getters y setters }
Creando el acceso a datos
Repositorio
@Repository public interface CursoRepository extends JpaRepository { }
Implementando la lógica de negocio
Servicio
@Service public class CursoService { @Autowired private CursoRepository repo; public List listar() { return repo.findAll(); } public Curso guardar(Curso curso) { return repo.save(curso); } public Optional buscar(Long id) { return repo.findById(id); } public void eliminar(Long id) { repo.deleteById(id); } }
Controlador REST para CRUD de Cursos
Listar todos los cursos
Método GET que devuelve una lista completa
Guardar un nuevo curso
Método POST que recibe un objeto JSON
Buscar un curso por ID
Método GET con parámetro de ruta
Eliminar un curso
Método DELETE con parámetro de ruta
@RestController @RequestMapping("/api/cursos") public class CursoController { @Autowired private CursoService servicio; @GetMapping public List listar() { return servicio.listar(); } @PostMapping public Curso guardar(@RequestBody Curso curso) { return servicio.guardar(curso); } @GetMapping("/{id}") public ResponseEntity obtener(@PathVariable Long id) { return servicio.buscar(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @DeleteMapping("/{id}") public ResponseEntity eliminar(@PathVariable Long id) { servicio.eliminar(id); return ResponseEntity.noContent().build(); } }
Ingrediente extra: Base de datos en memoria H2
¿Qué es H2?
H2 es una base de datos relacional escrita en Java. Es muy rápida, de código abierto, y puede funcionar en modo embebido (en memoria) o en modo servidor.
¿Por qué usar H2 con Spring Boot?
Es perfecta para desarrollo y pruebas porque se inicia rápidamente, no requiere instalación separada, y los datos se resetean al reiniciar la aplicación.
Configuración en application.properties
spring.h2.console.enabled=true spring.datasource.url=jdbc:h2:mem:cursosdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.hibernate.ddl-auto=update
Acceder a http://localhost:8080/h2-console para consultar la base de datos.
Validaciones con Bean Validation
Agregar dependencia:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
Usar anotaciones en la entidad:
public class Curso { @NotBlank private String nombre; @Size(min = 10, max = 200) private String descripcion; // ... }
Validar en el controlador:
@PostMapping public Curso guardar(@Valid @RequestBody Curso curso) { return servicio.guardar(curso); }
Uso de DTOs (Data Transfer Objects)
Evitar exponer entidades directamente. Crear clases DTO:
public class CursoDTO { private String nombre; private String descripcion; }
Convertir desde/hacia entidad:
public CursoDTO toDto(Curso curso) { CursoDTO dto = new CursoDTO(); dto.setNombre(curso.getNombre()); dto.setDescripcion(curso.getDescripcion()); return dto; }
Pruebas unitarias con Spring Boot
Agregar dependencia en pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
Ubicación del código de prueba
Los tests deben colocarse en el directorio src/test/java, siguiendo el mismo paquete que la clase que se desea probar. Por ejemplo, si la clase CursoService está en:
src/main/java/com/ejemplo/servicio/CursoService.java
El test deberá estar en:
src/test/java/com/ejemplo/servicio/CursoServiceTest.java
Ejemplo con JUnit:
@SpringBootTest public class CursoServiceTest { @Autowired private CursoService servicio; @Test public void testGuardarCurso() { Curso curso = new Curso(); curso.setNombre("Java Básico"); Curso resultado = servicio.guardar(curso); assertNotNull(resultado.getId()); } }
Cómo ejecutar las pruebas
Desde el IDE (por ejemplo IntelliJ IDEA o Eclipse):
  • Hacer clic derecho sobre el archivo CursoServiceTest.java y seleccionar Run o Run with Coverage.
Desde la línea de comandos con Maven:
./mvnw test
Esto ejecutará todos los tests definidos en src/test/java y mostrará el resultado en consola.
Agregar dependencia:
Relaciones entre entidades
Ejemplo: un curso tiene una lista de alumnos.
@Entity public class Alumno { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nombre; @ManyToOne private Curso curso; } @Entity public class Curso { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String nombre; @OneToMany(mappedBy = "curso") private List<Alumno> alumnos; }
¿Qué es @Service y para qué sirve?
La anotación @Service indica que una clase se comporta como un servicio dentro de la lógica de negocio de la aplicación. Spring la detecta automáticamente y la registra como un componente gestionado por el contenedor.
  • Se usa para separar la lógica del negocio del resto de la aplicación.
  • Facilita la reutilización y prueba de esa lógica.
Ejemplo:
@Service public class CalculadoraService { public int sumar(int a, int b) { return a + b; } }
¿Qué es @Repository y para qué sirve?
La anotación @Repository marca una clase como un componente de acceso a datos. Además de registrarla como componente, Spring proporciona capacidades adicionales como el manejo automático de excepciones relacionadas con la persistencia.
  • Se aplica a interfaces que extienden JpaRepository, CrudRepository, etc.
  • Se usa también en clases personalizadas de acceso a datos.
@Repository public interface ProductoRepository extends JpaRepository<Producto, Long> { }
¿Qué es @Component y para qué sirve?
@Component es la anotación genérica para marcar una clase como componente gestionado por Spring. A diferencia de @Service o @Repository, no tiene semántica de dominio asociada.
  • Se puede usar para cualquier clase que deba ser detectada e inyectada por Spring.
@Component public class GestorMensajes { public void enviar(String texto) { System.out.println("Mensaje enviado: " + texto); } }
Flujo completo de una aplicación Spring Boot

Petición HTTP
El cliente envía una solicitud al servidor
Controlador
Recibe la petición y la dirige al servicio adecuado
Servicio
Ejecuta la lógica de negocio y utiliza el repositorio
Repositorio
Interactúa con la base de datos y devuelve resultados
Spring Boot facilita este flujo mediante la inyección de dependencias y la configuración automática, permitiendo que los desarrolladores se centren en la lógica de negocio en lugar de en la infraestructura.
Beneficios de usar Spring Boot
70%
Reducción de código
Menos código boilerplate comparado con Spring tradicional
85%
Configuración automática
Porcentaje de configuraciones que Spring Boot maneja automáticamente
50%
Tiempo de desarrollo
Reducción aproximada en el tiempo de desarrollo de aplicaciones
Spring Boot actúa como un chef experto que nos permite crear aplicaciones Java sofisticadas sin preocuparnos por todos los detalles técnicos, permitiéndonos concentrarnos en lo que realmente importa: la lógica de negocio de nuestra aplicación.
Recetas avanzadas con Spring Boot
Spring Security
Añade autenticación y autorización a tu aplicación con configuraciones sencillas.
Spring Cloud
Desarrolla aplicaciones distribuidas y microservicios con facilidad.
Spring Data
Simplifica el acceso a datos con repositorios predefinidos para diferentes bases de datos.
Spring Test
Herramientas para probar cada capa de tu aplicación de forma aislada o integrada.
Una vez que domines los conceptos básicos de Spring Boot, puedes explorar estos módulos adicionales que te permitirán crear aplicaciones más robustas y completas, como un chef que domina técnicas culinarias avanzadas.