When developing an application, you often need different configurations for different environments. For example:
- In development, you might want verbose logging and a local database.
- In testing, you might use a mock service or in-memory database.
- In production, you need optimized settings, security, and real services.
Managing these differences manually can be messy. This is where Profiles in Spring Boot come to the rescue.
In this guide, we’ll walk you through:
- ✅ What are Spring Profiles?
- ✅ How to create and structure environment-specific configurations
- ✅ How to activate and switch between profiles
- ✅ How to load profile-specific beans
- ✅ Best practices and common pitfalls

✅ What Are Spring Profiles?
Spring Profiles allow developers to create logical groupings of beans and configurations which can be registered and activated conditionally. This means you can isolate your configurations and activate only the ones relevant for a specific environment.
For example:
- Load
application-dev.properties
for development - Load
application-prod.properties
for production
With profiles, Spring Boot lets you:
- Control which configuration files are loaded
- Customize bean definitions per environment
- Simplify deployment and reduce configuration errors
📁 Creating Environment-Specific Property Files
Spring Boot, by default, looks for a file named application.properties
or application.yml
. To use profiles, you create profile-specific files.
🔸 Using .properties
1 2 3 4 5 6 |
application.properties # Shared/default config application-dev.properties # Development environment application-test.properties # Testing environment application-prod.properties # Production environment |
Each of these files can contain different property values depending on the environment.
Example:
application-dev.properties
1 2 3 4 5 6 |
server.port=8081 spring.datasource.url=jdbc:h2:mem:devdb logging.level.root=DEBUG |
application-prod.properties
1 2 3 4 5 |
server.port=8080 spring.datasource.url=jdbc:postgresql://prod-db-server:5432/mydb logging.level.root=ERROR |
🔸 Using application.yml
with Profiles
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
spring: profiles: active: dev --- spring: profiles: dev server: port: 8081 app: message: Hello from DEV! --- spring: profiles: prod server: port: 8080 app: message: Hello from PROD! |
🚀 Activating a Profile
Spring Boot provides multiple ways to activate a profile.
✅ 1. In application.properties
or application.yml
1 2 3 |
spring.profiles.active=dev |
✅ 2. Via Command Line
1 2 3 |
java -jar your-app.jar --spring.profiles.active=prod |
✅ 3. As an Environment Variable (e.g., in Docker or CI)
1 2 |
export SPRING_PROFILES_ACTIVE=test |
✅ 4. JVM System Property (useful in IDEs)
1 2 3 4 |
-Dspring.profiles.active=prod |
💡 Tip: Never hardcode production profiles inside the code. Use command-line or environment variables to control it externally.
🧠 Using @Profile
to Load Beans Conditionally
Spring allows you to load specific beans only for a particular profile.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@Configuration public class AppConfig { @Bean @Profile("dev") public DataSource devDataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .build(); } @Bean @Profile("prod") public DataSource prodDataSource() { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setUrl("jdbc:postgresql://prod-db:5432/mydb"); ds.setUsername("produser"); ds.setPassword("securepass"); return ds; } } |
With this setup:
- If the active profile is
dev
, you get an H2 in-memory database. - If the active profile is
prod
, you connect to a production PostgreSQL database.
🧪 Sample Controller to Demonstrate Profiles
1. Add a Message in application-dev.properties
1 2 3 4 |
app.message=Running in DEV mode! |
2. Add a Message in application-prod.properties
1 2 3 4 |
app.message=Running in PROD mode! |
3. Use in a Controller
1 2 3 4 5 6 7 8 9 10 11 12 |
@RestController public class ProfileController { @Value("${app.message}") private String message; @GetMapping("/profile-info") public String getProfileInfo() { return message; } } |
Output
- If
spring.profiles.active=dev
, response will be:
“Running in DEV mode!” - If
spring.profiles.active=prod
, response will be:
“Running in PROD mode!”
⚠️ Common Pitfalls
🔸 Not setting any profile: If no active profile is defined, only application.properties
is used. Spring won’t load any application-<profile>.properties
files unless a profile is active.
🔸 Conflicting properties: If the same key exists in application.properties
and a profile-specific file, the profile-specific value will override the default.
🔸 Forgetting to use @Profile
: Even if the profile is active, beans without @Profile
annotations will always be created.
✅ Best Practices
✅ Use profile-specific files to isolate configurations.
✅ Keep sensitive information like passwords out of source control—use environment variables or external config services.
✅ Set a default profile or provide fallback behavior.
✅ Document which profiles are supported and when to use them.
📌 Summary
Feature | Benefit |
---|---|
application-<profile>.properties | Customizes properties per environment |
spring.profiles.active | Lets you switch environments dynamically |
@Profile | Controls bean loading based on active profile |
Multiple activation options | Flexible for local, CI/CD, cloud |
🎯 Final Thoughts
Spring Boot profiles provide an elegant and flexible way to manage configuration across different stages of application development. With just a bit of setup, you can easily avoid config-related errors and ensure your app behaves as expected in each environment.
“Environment-specific configuration is no longer a hassle with Spring Profiles.”