Saltar al contenido principal

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):

  1. file:./config/application.properties
  2. file:./config/application.yml
  3. file:./application.properties
  4. file:./application.yml
  5. classpath:/config/application.properties
  6. classpath:/config/application.yml
  7. classpath:/application.properties
  8. classpath:/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​

Criteriopropertiesyml
Legibilidad⭐⭐⭐⭐⭐⭐⭐⭐
Simplicidad⭐⭐⭐⭐⭐⭐⭐⭐
EstructuraPlanaJerárquica
RepeticiónMuchaPoca
ListasDifícilFácil
CompatibilidadUniversalRequiere parser
ErroresRarosIndentació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:

ValorDescripciónUso
noneNinguna acciónProducción
validateValidar solo el esquemaProducción
updateActualizar el esquemaDesarrollo
createCrear el esquema al iniciarPruebas
create-dropCrear y luego eliminarPruebas

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:

  1. Cree un proyecto Spring Boot
  2. En application.properties, configure:
    • Puerto: 8081
    • Nombre: "My Greeting App"
  3. Inicie la aplicación
  4. 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:

  1. Añada en application.yml:
    app:
    welcome-message: ¡Bienvenido!
    max-users: 100
  2. Cree un controlador que muestre estos valores
  3. Pruebe

Ejercicio 4: Profiles​

Objetivo: Crear profiles dev y prod

Instrucciones:

  1. Cree application-dev.yml:
    • Puerto: 8080
    • Logs: DEBUG
  2. Cree application-prod.yml:
    • Puerto: 80
    • Logs: WARN
  3. Pruebe la activación de cada profile

Preguntas de Repaso​

  1. ¿Cuál es la diferencia entre application.properties y application.yml?

  2. ¿Cómo activar un profile en Spring Boot?

  3. ¿Cuál es el orden de prioridad de los archivos de configuración?

  4. ¿Cómo inyectar una propiedad personalizada en una clase?

  5. ¿Qué anotación se utiliza para una clase de configuración con varias propiedades?

  6. ¿Cómo usar una variable de entorno en application.yml?

  7. ¿Cuáles son los valores posibles para spring.jpa.hibernate.ddl-auto?

  8. ¿Por qué nunca debe subir contraseñas en application.properties?


Resumen del Capítulo​

Puntos Clave​

  • Spring Boot soporta .properties y .yml
  • .yml es más legible para estructuras complejas
  • Los profiles permiten configuraciones por entorno
  • @Value para una propiedad, @ConfigurationProperties para 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

Volver al Módulo 2