Properties & YAML
Spring Boot externalizes configuration so the same artifact runs in dev, test, and production with different settings. The two most common sources are the application.properties and application.yml files in src/main/resources. This page covers both formats, how property names bind, the most useful keys, and how Spring Boot decides which value wins.
Two formats, one model
You can configure Boot with either a flat .properties file or a hierarchical .yml file. They express the same thing, so pick the one your team prefers (do not use both for the same keys).
# application.properties
server.port=8081
spring.application.name=catalog-service
spring.datasource.url=jdbc:postgresql://localhost:5432/catalog
spring.datasource.username=app
spring.datasource.password=secret
# application.yml
server:
port: 8081
spring:
application:
name: catalog-service
datasource:
url: jdbc:postgresql://localhost:5432/catalog
username: app
password: secret
Note: YAML’s nesting is concise for grouped keys, but it is whitespace-sensitive, indentation must use spaces, never tabs. Properties files are flatter and harder to get wrong. Both are loaded the same way.
Relaxed binding
Spring Boot uses relaxed binding, so a single property can be written several ways and still map to the same target. For a property bound to a field named appUserName, all of these match:
| Form | Example |
|---|---|
| Kebab case (recommended) | app.user-name |
| Camel case | app.userName |
| Underscore | app.user_name |
| Upper-case env var | APP_USERNAME |
This is why an environment variable like SERVER_PORT=9000 overrides server.port, the same mechanism that makes configuration portable across containers and CI.
Tip: Use kebab-case in your files (
my-app.read-timeout) and rely on relaxed binding to accept environment-variable overrides at deploy time. It is the most readable and the documented convention.
Common Spring Boot properties
A small set of keys covers most applications. These are all built-in keys consumed by auto-configuration.
# Server
server.port=8080
server.servlet.context-path=/api
# Application + profiles
spring.application.name=catalog-service
spring.profiles.active=dev
# Datasource (relational)
spring.datasource.url=jdbc:mysql://localhost:3306/catalog
spring.datasource.username=root
spring.datasource.password=secret
# JPA / Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# Logging
logging.level.root=INFO
logging.level.com.devcraftly=DEBUG
Warning: Never commit real secrets (passwords, API keys) to
application.propertiesin version control. Inject them through environment variables, a secrets manager, or externalized config instead.
Profile-specific files
Profiles let you keep environment-specific values in separate files. Spring Boot loads application-{profile}.properties (or .yml) on top of the base file when that profile is active.
src/main/resources/
├── application.properties # shared defaults
├── application-dev.properties # active when 'dev' profile is on
└── application-prod.properties # active when 'prod' profile is on
Activate a profile with the spring.profiles.active property, a command-line argument, or an environment variable:
java -jar app.jar --spring.profiles.active=prod
# or
SPRING_PROFILES_ACTIVE=prod java -jar app.jar
A single YAML file can also hold multiple profile documents separated by ---:
spring:
config:
activate:
on-profile: dev
server:
port: 8080
---
spring:
config:
activate:
on-profile: prod
server:
port: 80
See profiles for the full story on grouping and conditional beans per environment.
Precedence: who wins?
When the same key is defined in several places, Spring Boot applies a well-defined order. Sources later in this list override earlier ones (this is a simplified view of the most common sources):
application.properties/application.ymlpackaged inside the jar.- Profile-specific files inside the jar (
application-prod.properties). - The same files placed outside the jar (in the working directory or a
/configfolder). - OS environment variables (via relaxed binding).
- Java system properties (
-Dserver.port=9000). - Command-line arguments (
--server.port=9000).
# Command-line arg beats everything in the files
java -jar app.jar --server.port=9090
Output:
Tomcat started on port 9090 (http) with context path '/api'
Note: The practical takeaway: bake sensible defaults into your packaged files, then override per environment with profile files, environment variables, or command-line arguments, no rebuild required.
Binding properties into your code
You can read individual values with @Value("${server.port}"), but for grouped settings prefer a typed @ConfigurationProperties class. Both approaches, plus validation of config, are covered under configuration.