Spring Boot
¿Qué es Spring Boot?
Spring Boot simplifica la creación de aplicaciones Spring con configuración mínima.
Ventajas:
- Configuración automática
- Servidor embebido (Tomcat, Jetty)
- Sin XML, solo anotaciones y código
- Ecosistema completo (Web, Data, Security, etc.)
Crear proyecto
Spring Initializr
Configuración:
- Project: Maven o Gradle
- Language: Java
- Spring Boot: 3.2.x (última versión)
- Java: 17 o 21
- Dependencies: Spring Web, Spring Data JPA, PostgreSQL, Lombok
O con CLI:
curl https://start.spring.io/starter.zip \ -d dependencies=web,data-jpa,postgresql,lombok \ -d javaVersion=21 \ -d type=maven-project \ -o demo.zip
unzip demo.zipcd demoEstructura de proyecto
src/├── main/│ ├── java/│ │ └── com/ejemplo/demo/│ │ ├── DemoApplication.java # Main│ │ ├── controller/ # REST controllers│ │ ├── service/ # Lógica de negocio│ │ ├── repository/ # Acceso a datos│ │ ├── model/ # Entidades│ │ ├── dto/ # Data Transfer Objects│ │ └── config/ # Configuración│ └── resources/│ ├── application.properties # Configuración│ └── application-dev.properties # Perfil dev└── test/ └── java/ └── com/ejemplo/demo/Clase principal
@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}@SpringBootApplication equivale a:
@Configuration: Clase de configuración@EnableAutoConfiguration: Configuración automática@ComponentScan: Escanea componentes en el paquete
Configuración
application.properties
# Servidorserver.port=8080
# Base de datosspring.datasource.url=jdbc:postgresql://localhost:5432/demospring.datasource.username=postgresspring.datasource.password=secret
# JPAspring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=truespring.jpa.properties.hibernate.format_sql=true
# Logginglogging.level.com.ejemplo=DEBUGlogging.level.org.springframework=INFOapplication.yml (alternativa)
server: port: 8080
spring: datasource: url: jdbc:postgresql://localhost:5432/demo username: postgres password: secret jpa: hibernate: ddl-auto: update show-sql: true
logging: level: com.ejemplo: DEBUG org.springframework: INFOPerfiles
application-dev.properties
spring.datasource.url=jdbc:h2:mem:testdbspring.jpa.show-sql=trueapplication-prod.properties
spring.datasource.url=jdbc:postgresql://prod-server:5432/demospring.jpa.show-sql=falseActivar perfil:
# Línea de comandosjava -jar app.jar --spring.profiles.active=dev
# Variable de entornoexport SPRING_PROFILES_ACTIVE=prodInyección de dependencias
@Autowired
@Servicepublic class UsuarioServicio {
@Autowired private UsuarioRepositorio repositorio;
public Usuario buscar(Long id) { return repositorio.findById(id).orElseThrow(); }}Constructor injection (recomendado)
@Servicepublic class UsuarioServicio {
private final UsuarioRepositorio repositorio;
// @Autowired es opcional en constructores (Spring 4.3+) public UsuarioServicio(UsuarioRepositorio repositorio) { this.repositorio = repositorio; }}Con Lombok
@Service@RequiredArgsConstructorpublic class UsuarioServicio {
private final UsuarioRepositorio repositorio;
// Constructor generado automáticamente}Componentes de Spring
@Component
Componente genérico.
@Componentpublic class EmailUtil { public void enviar(String destinatario, String mensaje) { // ... }}@Service
Capa de servicio (lógica de negocio).
@Servicepublic class UsuarioServicio { public Usuario crear(String nombre) { // ... }}@Repository
Capa de acceso a datos.
@Repositorypublic interface UsuarioRepositorio extends JpaRepository<Usuario, Long> { Usuario findByEmail(String email);}@Controller / @RestController
Controladores web.
@RestController@RequestMapping("/api/usuarios")public class UsuarioController { // ...}Configuración personalizada
@Configuration
@Configurationpublic class AppConfig {
@Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.INDENT_OUTPUT, true); return mapper; }
@Bean public RestTemplate restTemplate() { return new RestTemplate(); }}@Value
Inyectar valores de configuración.
@Componentpublic class AppProperties {
@Value("${app.nombre}") private String nombre;
@Value("${app.version:1.0}") // Valor por defecto private String version;}@ConfigurationProperties
@ConfigurationProperties(prefix = "app")@Componentpublic class AppProperties { private String nombre; private String version; private int timeout;
// Getters y setters}application.properties:
app.nombre=Mi Appapp.version=1.0app.timeout=5000Eventos
Publicar eventos
@Service@RequiredArgsConstructorpublic class UsuarioServicio {
private final ApplicationEventPublisher eventPublisher;
public void crear(Usuario usuario) { // Guardar usuario
eventPublisher.publishEvent(new UsuarioCreadoEvent(usuario)); }}Escuchar eventos
@Componentpublic class UsuarioEventListener {
@EventListener public void onUsuarioCreado(UsuarioCreadoEvent event) { System.out.println("Usuario creado: " + event.getUsuario().getNombre()); }}Tareas programadas
@Scheduled
@Componentpublic class TareasProgramadas {
@Scheduled(fixedRate = 60000) // Cada 60 segundos public void tarea1() { System.out.println("Ejecutando tarea cada minuto"); }
@Scheduled(cron = "0 0 2 * * ?") // Todos los días a las 2am public void tarea2() { System.out.println("Limpieza nocturna"); }}Habilitar scheduling:
@SpringBootApplication@EnableSchedulingpublic class DemoApplication { // ...}Actuator
Endpoints de monitoreo y métricas.
Dependencia
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency>Configuración
management.endpoints.web.exposure.include=health,info,metricsmanagement.endpoint.health.show-details=alwaysEndpoints
/actuator/health: Estado de salud/actuator/info: Información de la app/actuator/metrics: Métricas (memoria, CPU, etc.)/actuator/env: Variables de entorno
Profiles avanzados
Configuración específica
@Configuration@Profile("dev")public class DevConfig {
@Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .build(); }}
@Configuration@Profile("prod")public class ProdConfig {
@Bean public DataSource dataSource() { // PostgreSQL real }}CommandLineRunner
Ejecutar código al iniciar la aplicación.
@Componentpublic class DataLoader implements CommandLineRunner {
@Autowired private UsuarioRepositorio repositorio;
@Override public void run(String... args) throws Exception { if (repositorio.count() == 0) { repositorio.save(new Usuario("Admin", "admin@email.com")); System.out.println("Datos iniciales cargados"); } }}Despliegue
JAR ejecutable
# Mavenmvn clean package
# Gradlegradle build
# Ejecutarjava -jar target/demo-0.0.1-SNAPSHOT.jarDocker
Dockerfile:
FROM eclipse-temurin:21-jre-alpineWORKDIR /appCOPY target/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]docker build -t mi-app .docker run -p 8080:8080 mi-appBuenas prácticas
- Constructor injection: Más testeable y inmutable.
- Perfiles: Separar configuración dev/prod.
- application.yml: Más legible que
.properties. - @ConfigurationProperties: Para configuración compleja.
- Actuator: Monitoreo en producción.
- Lombok: Reduce boilerplate con
@RequiredArgsConstructor.
Próximo paso
Aprende a crear APIs REST: REST APIs →