Profiles in Spring Boot
Profiles in Spring Boot
Real applications behave differently in different environments: the database URL in development points to a local container, in staging it points to a shared QA server, and in production it points to a hardened RDS cluster. You do not want to change code between deployments — you want the same JAR to adapt its behaviour based on where it runs. That is exactly what Spring Profiles deliver.
What a Profile Is
A profile is a named group of configuration that Spring activates on demand. When a profile is active, any beans, property files, or configuration classes associated with that profile are loaded. Everything else is ignored. Think of it as a set of overrides applied on top of the base configuration.
Common profile names you will encounter in real projects:
- dev — local development (H2 in-memory database, verbose logging, no real email)
- test — automated tests (same H2 or a Testcontainers instance, fast startup)
- staging — integration environment that mirrors production structure
- prod — production (real databases, connection pools, secrets from a vault)
prod and eu-west to combine production-grade settings with a region-specific data-residency configuration. Spring merges their properties and beans; later-listed profiles win on conflicts.
Profile-Specific Property Files
The simplest way to supply profile-specific values is with a dedicated properties file. Spring Boot follows an automatic naming convention:
Place all four files in src/main/resources. The base file holds defaults; profile-specific files override or add to them. Here is a typical split:
Notice that application-prod.properties delegates credentials to environment variables via the ${VAR} placeholder syntax. The profile file controls which settings exist; secrets are injected at deploy time.
Activating a Profile
There are several ways to tell Spring Boot which profile to use:
1. Environment variable (preferred in containers and CI/CD):
2. JVM system property:
3. In application.properties (for local defaults only):
4. In tests with @ActiveProfiles:
spring.profiles.active=prod to a shared properties file. The active profile is an operational decision, not a code decision. Set it in your deployment pipeline (Docker ENV, Kubernetes env var, CI/CD step) so the same artifact can be promoted from staging to production without rebuilding.
Profile-Specific Beans with @Profile
Profiles are not only for properties. You can gate entire Spring beans on a profile using the @Profile annotation. This is powerful when you need a completely different implementation in different environments — for example, a real email sender in production and a no-op stub locally.
The ! prefix negates the condition. You can also use the Spring Expression Language (SpEL) form @Profile({"prod", "staging"}) to activate a bean when either profile is active, or @Profile("prod & cloud") to require both.
Profile Groups (Spring Boot 2.4+)
Starting with Spring Boot 2.4, you can define profile groups — a single high-level name that expands to several concrete profiles. This avoids forcing callers to remember a long list of comma-separated profile names.
Now launching with SPRING_PROFILES_ACTIVE=production automatically activates prod, monitoring, and cloud-aws together. Your CI/CD pipeline stays clean, and each sub-profile can focus on a single concern.
The Default Profile
If no profile is activated, Spring uses the built-in default profile. Any bean annotated with @Profile("default") is only registered when nothing else is active. This is a convenient safety net for ensuring at least some beans are present during quick ad-hoc runs, but in practice most teams always set an explicit active profile.
@Profile, it loads in every environment — including production. A development-only data-seeding bean that lacks @Profile("dev") could silently insert test data in production on the next deploy.
Inspecting the Active Profile at Runtime
You can inject the currently active profiles programmatically via the Environment abstraction:
This is especially useful in startup log messages or admin endpoints to make it immediately obvious which environment a running instance belongs to.
Summary
Spring Profiles let you ship a single artifact and adapt its behaviour per environment without touching code. Name your profiles clearly (dev, test, staging, prod), keep credentials out of all profile files (delegate them to environment variables), and activate the right profile from the deployment pipeline rather than from committed source. Use @Profile on beans for implementation swapping, and profile groups to compose complex environments from focused building blocks. In the next lesson you will see how YAML provides a more structured and concise alternative to properties files, including multi-document YAML for keeping all profiles in one file.