Capítulo 3: Configuración con application.properties y application.yml
Introducción
La configuración es un aspecto fundamental de cualquier aplicación. Spring Boot ofrece un sistema de configuración potente y flexible que permite personalizar el comportamiento de la aplicación sin modificar el código.
Objetivos del Capítulo
Al final de este capítulo, usted será capaz de:
- Configurar una aplicación con application.properties y application.yml
- Utilizar las propiedades predefinidas de Spring Boot
- Crear propiedades personalizadas
- Gestionar diferentes entornos con los profiles
- Externalizar la configuración
Archivos de Configuración
Localización
Spring Boot busca los archivos de configuración en este orden:
Orden de prioridad (de mayor a menor):
file:./config/application.propertiesfile:./config/application.ymlfile:./application.propertiesfile:./application.ymlclasspath:/config/application.propertiesclasspath:/config/application.ymlclasspath:/application.propertiesclasspath:/application.yml
En la práctica: Coloque sus archivos en src/main/resources/
Formato application.properties
Sintaxis Básica
Formato:
clave=valor
Características:
- Formato simple clave-valor
- Sin indentación
- Comentarios con
# - Repetición de prefijos
Ejemplo Completo
# Configuración del servidor
server.port=8080
server.servlet.context-path=/api
# Nombre de la aplicación
spring.application.name=greeting-app
# Configuración de la base de datos
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret
spring.datasource.driver-class-name=org.postgresql.Driver
# Configuración JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
# Configuración de logs
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.level.org.springframework.web=DEBUG
logging.file.name=logs/application.log
# Configuración Jackson (JSON)
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=America/Montreal
spring.jackson.serialization.indent-output=true
Ventajas y Desventajas
Ventajas:
- Formato simple y ampliamente conocido
- Compatible con Java Properties
- Sin dependencias externas
Desventajas:
- Repetitivo para estructuras jerárquicas
- Menos legible para configuraciones complejas
Formato application.yml
Sintaxis Básica
Formato: YAML (YAML Ain't Markup Language)
Características:
- Formato jerárquico con indentación
- Indentación = 2 o 4 espacios (NO tabs)
- Estructura en árbol
- Más conciso
Ejemplo Completo
# Configuración del servidor
server:
port: 8080
servlet:
context-path: /api
# Nombre de la aplicación
spring:
application:
name: greeting-app
# Configuración de la base de datos
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
driver-class-name: org.postgresql.Driver
# Configuración JPA
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.PostgreSQLDialect
# Configuración Jackson
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: America/Montreal
serialization:
indent-output: true
# Configuración de logs
logging:
level:
root: INFO
com.example: DEBUG
org.springframework.web: DEBUG
file:
name: logs/application.log
Ventajas y Desventajas
Ventajas:
- Más legible para estructuras complejas
- Menos repetición
- Soporte de listas y mapas
- Formato moderno
Desventajas:
- Sensible a la indentación
- Errores de sintaxis más frecuentes
- Requiere la dependencia SnakeYAML (incluida por defecto)
Comparación properties vs yml
Misma Configuración en Ambos Formatos
application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret
application.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
Tabla Comparativa
| Criterio | properties | yml |
|---|---|---|
| Legibilidad | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Simplicidad | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Estructura | Plana | Jerárquica |
| Repetición | Mucha | Poca |
| Listas | Difícil | Fácil |
| Compatibilidad | Universal | Requiere parser |
| Errores | Raros | Indentación |
Recomendación: Utilice .yml para configuraciones complejas, .properties para configuraciones simples.
Propiedades Comunes de Spring Boot
1. Configuración del Servidor
server:
port: 8080 # Puerto del servidor
servlet:
context-path: /api # Ruta base
compression:
enabled: true # Compresión GZIP
error:
include-message: always # Incluir mensajes de error
2. Configuración de la Base de Datos
PostgreSQL
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
driver-class-name: org.postgresql.Driver
MySQL
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
H2 (Base de datos en memoria - Pruebas)
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
h2:
console:
enabled: true # Consola H2 accesible
path: /h2-console
3. Configuración JPA/Hibernate
spring:
jpa:
hibernate:
ddl-auto: update # none, validate, update, create, create-drop
show-sql: true # Mostrar las consultas SQL
properties:
hibernate:
format_sql: true # Formatear las consultas
dialect: org.hibernate.dialect.PostgreSQLDialect
use_sql_comments: true # Comentar las consultas
Valores de ddl-auto:
| Valor | Descripción | Uso |
|---|---|---|
| none | Ninguna acción | Producción |
| validate | Validar solo el esquema | Producción |
| update | Actualizar el esquema | Desarrollo |
| create | Crear el esquema al iniciar | Pruebas |
| create-drop | Crear y luego eliminar | Pruebas |
4. Configuración de Logs
logging:
level:
root: INFO # Nivel global
com.example: DEBUG # Su aplicación
org.springframework.web: DEBUG # Spring Web
org.hibernate.SQL: DEBUG # Consultas SQL
org.hibernate.type: TRACE # Parámetros SQL
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss} - %msg%n'
file:
name: logs/application.log # Archivo de log
max-size: 10MB # Tamaño máximo por archivo
Niveles de log:
TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
5. Configuración Jackson (JSON)
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: America/Montreal
serialization:
indent-output: true # JSON indentado
write-dates-as-timestamps: false
deserialization:
fail-on-unknown-properties: false
6. Configuración DevTools
spring:
devtools:
restart:
enabled: true # Reinicio automático
livereload:
enabled: true # Recarga del navegador
Propiedades Personalizadas
Crear Propiedades Personalizadas
application.yml:
app:
name: Greeting Application
version: 1.0.0
admin:
email: admin@example.com
phone: +1-514-123-4567
security:
jwt-secret: mySecretKey123
jwt-expiration: 86400000 # 24 horas en ms
Inyección con @Value
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
@Value("${app.admin.email}")
private String adminEmail;
public void printConfig() {
System.out.println("Application: " + appName);
System.out.println("Version: " + appVersion);
System.out.println("Admin Email: " + adminEmail);
}
}
Clase de Configuración con @ConfigurationProperties
Enfoque recomendado para varias propiedades:
application.yml:
app:
security:
jwt-secret: mySecretKey123
jwt-expiration: 86400000
allowed-origins:
- http://localhost:3000
- http://localhost:4200
Clase de configuración:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@ConfigurationProperties(prefix = "app.security")
public class SecurityProperties {
private String jwtSecret;
private Long jwtExpiration;
private List<String> allowedOrigins;
// Getters y Setters
public String getJwtSecret() {
return jwtSecret;
}
public void setJwtSecret(String jwtSecret) {
this.jwtSecret = jwtSecret;
}
public Long getJwtExpiration() {
return jwtExpiration;
}
public void setJwtExpiration(Long jwtExpiration) {
this.jwtExpiration = jwtExpiration;
}
public List<String> getAllowedOrigins() {
return allowedOrigins;
}
public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
}
Uso:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AuthService {
@Autowired
private SecurityProperties securityProperties;
public void generateToken() {
String secret = securityProperties.getJwtSecret();
Long expiration = securityProperties.getJwtExpiration();
// Lógica de generación de token
}
}
Gestión de Profiles
Concepto de Profiles
Los profiles permiten tener configuraciones diferentes según el entorno.
Crear Profiles
Estructura de archivos:
src/main/resources/
├── application.yml # Configuración común
├── application-dev.yml # Desarrollo
├── application-test.yml # Pruebas
└── application-prod.yml # Producción
Configuración por Profile
application.yml (común):
spring:
application:
name: greeting-app
app:
name: Greeting Application
application-dev.yml:
server:
port: 8080
spring:
datasource:
url: jdbc:h2:mem:testdb
h2:
console:
enabled: true
logging:
level:
root: DEBUG
application-test.yml:
server:
port: 8081
spring:
datasource:
url: jdbc:h2:mem:testdb
logging:
level:
root: INFO
application-prod.yml:
server:
port: 80
spring:
datasource:
url: jdbc:postgresql://prod-db.example.com:5432/mydb
username: ${DB_USERNAME} # Variable de entorno
password: ${DB_PASSWORD}
logging:
level:
root: WARN
file:
name: /var/log/app/application.log
Activar un Profile
Método 1: En application.yml
spring:
profiles:
active: dev
Método 2: Línea de comandos
java -jar app.jar --spring.profiles.active=prod
Método 3: Variable de entorno
export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar
Método 4: En el IDE
VS Code (launch.json):
{
"configurations": [
{
"type": "java",
"name": "Spring Boot App",
"request": "launch",
"mainClass": "com.example.greeting.GreetingApplication",
"args": "--spring.profiles.active=dev"
}
]
}
Profiles Múltiples
Puede activar varios profiles:
java -jar app.jar --spring.profiles.active=dev,local
Orden de prioridad: El último profile tiene la prioridad
Variables de Entorno
Uso
Spring Boot puede leer variables de entorno:
application.yml:
spring:
datasource:
url: ${DATABASE_URL:jdbc:postgresql://localhost:5432/mydb}
username: ${DATABASE_USER:postgres}
password: ${DATABASE_PASSWORD:secret}
Sintaxis: ${NOMBRE_VARIABLE:valor_por_defecto}
Definir Variables
Windows (CMD):
set DATABASE_URL=jdbc:postgresql://prod-server:5432/mydb
set DATABASE_USER=admin
set DATABASE_PASSWORD=supersecret
java -jar app.jar
Windows (PowerShell):
$env:DATABASE_URL="jdbc:postgresql://prod-server:5432/mydb"
$env:DATABASE_USER="admin"
$env:DATABASE_PASSWORD="supersecret"
java -jar app.jar
Linux/macOS:
export DATABASE_URL=jdbc:postgresql://prod-server:5432/mydb
export DATABASE_USER=admin
export DATABASE_PASSWORD=supersecret
java -jar app.jar
Configuración Externalizada
Archivo de Configuración Externo
Spring Boot puede cargar archivos de configuración externos:
Estructura:
/opt/app/
├── app.jar
└── config/
└── application.yml
Lanzamiento:
java -jar /opt/app/app.jar
Spring Boot encontrará automáticamente /opt/app/config/application.yml
Especificar un Archivo
java -jar app.jar --spring.config.location=file:/path/to/config/
Propiedades Sensibles
Proteger Contraseñas
Mala práctica:
spring:
datasource:
password: supersecret123 # ❌ Contraseña en texto plano
Buenas prácticas:
1. Variables de entorno:
spring:
datasource:
password: ${DATABASE_PASSWORD} # ✅ Variable de entorno
2. Spring Cloud Config Server:
- Centralizar la configuración
- Cifrado de propiedades sensibles
3. HashiCorp Vault:
- Gestión profesional de secretos
4. Archivos .env (solo desarrollo):
DATABASE_PASSWORD=secret
Importante: ¡Nunca suba contraseñas a Git!
Ejercicios Prácticos
Ejercicio 1: Configuración Básica
Objetivo: Configurar el puerto y el nombre de la aplicación
Instrucciones:
- Cree un proyecto Spring Boot
- En
application.properties, configure:- Puerto: 8081
- Nombre: "My Greeting App"
- Inicie la aplicación
- Verifique que el servidor arranca en el puerto 8081
Ejercicio 2: Conversión properties → yml
Objetivo: Convertir un archivo properties a yml
Archivo properties dado:
server.port=8080
spring.application.name=user-service
spring.datasource.url=jdbc:postgresql://localhost:5432/users
spring.datasource.username=admin
spring.jpa.show-sql=true
A realizar: Convierta al formato YAML
Ejercicio 3: Propiedades Personalizadas
Objetivo: Crear y utilizar propiedades personalizadas
Instrucciones:
- Añada en
application.yml:app:
welcome-message: ¡Bienvenido!
max-users: 100 - Cree un controlador que muestre estos valores
- Pruebe
Ejercicio 4: Profiles
Objetivo: Crear profiles dev y prod
Instrucciones:
- Cree
application-dev.yml:- Puerto: 8080
- Logs: DEBUG
- Cree
application-prod.yml:- Puerto: 80
- Logs: WARN
- Pruebe la activación de cada profile
Preguntas de Repaso
-
¿Cuál es la diferencia entre application.properties y application.yml?
-
¿Cómo activar un profile en Spring Boot?
-
¿Cuál es el orden de prioridad de los archivos de configuración?
-
¿Cómo inyectar una propiedad personalizada en una clase?
-
¿Qué anotación se utiliza para una clase de configuración con varias propiedades?
-
¿Cómo usar una variable de entorno en application.yml?
-
¿Cuáles son los valores posibles para
spring.jpa.hibernate.ddl-auto? -
¿Por qué nunca debe subir contraseñas en application.properties?
Resumen del Capítulo
Puntos Clave
- Spring Boot soporta
.propertiesy.yml .ymles más legible para estructuras complejas- Los profiles permiten configuraciones por entorno
@Valuepara una propiedad,@ConfigurationPropertiespara varias- Utilizar variables de entorno para datos sensibles
- Nunca subir contraseñas
Buenas Prácticas
- Utilizar profiles para cada entorno
- Externalizar las configuraciones sensibles
- Documentar las propiedades personalizadas
- Proveer valores por defecto
- Usar nombres de propiedades descriptivos
- Separar configuración común y específica
Próximos Pasos
En el siguiente capítulo, estudiaremos:
Capítulo 4: Anotaciones Básicas
- @SpringBootApplication
- @RestController vs @Controller
- @GetMapping, @PostMapping, etc.
- @Autowired e inyección de dependencias
- @Component, @Service, @Repository