Imagine you need to manage different parameters of your system for different environments — for example, development (development), test (test) and production (production). In the Spring world this is easily achieved with configuration profiles.
Why do this?
- Different settings per environment. For example, you might use a local database for development and a cloud one for production.
- Switch configurations on the fly. Change settings without rewriting code.
- Improved security. Sensitive production parameters can be stored separately.
If profiles didn't exist, you'd probably keep separate configuration files for each environment and manually copy the right one before startup. Sounds annoying — Spring saves us from that routine.
How do profiles work in Spring Boot?
In Spring Boot each profile represents a set of configurations that are applied only when that profile is active. The key idea is that you can define different settings for different profiles, and Spring will pick the right configs based on the active profile.
For example, if you have profiles dev and prod, Spring can use the configurations for one of them depending on which profile is active.
How are profiles specified?
In Spring Boot profiles can be set:
- In configuration files.
- Via command line parameters.
- Through environment variables.
Configuring profiles in Spring Boot
1. Using application.properties and application.yml
Spring Boot uses configuration files to manage application settings. By default these are:
application.propertiesapplication.yml
Additionally you can create files for specific profiles. For example:
application-dev.properties(or.yml) — settings for thedevprofile.application-prod.properties(or.yml) — settings for theprodprofile.
On application startup Spring will automatically pick the configuration file that matches the active profile.
Example: application.yml
spring:
profiles:
active: dev
application-dev.yml
app:
name: "MyApp (Development)"
datasource:
url: "jdbc:h2:mem:devdb"
username: "dev_user"
password: "dev_password"
application-prod.yml
app:
name: "MyApp (Production)"
datasource:
url: "jdbc:mysql://prod.server:3306/proddb"
username: "prod_user"
password: "prod_password"
When the dev profile is active, Spring will load settings from application-dev.yml. If prod is active, it will take settings from application-prod.yml.
2. Switching profiles
Via application.properties
If you want to set a default profile, just add it to application.properties:
spring.profiles.active=dev
Via the command line
You can activate a profile when starting the application:
java -jar myapp.jar --spring.profiles.active=prod
Via environment variables
You can set the profile using an environment variable:
export SPRING_PROFILES_ACTIVE=prod
3. Using the @Profile annotation
Spring also allows profile control at the component level. With the @Profile annotation you can specify under which profile a particular bean should be created.
Example:
Configuration code:
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
// Configuration for the dev profile
return new HikariDataSource();
}
@Bean
@Profile("prod")
public DataSource prodDataSource() {
// Configuration for the prod profile
return new HikariDataSource();
}
}
Now Spring will create the DataSource bean depending on the active profile.
Practice: implementing profiles in a Spring Boot application
1. Project setup
Create a new project on Spring Initializr. Add required dependencies such as:
- Spring Boot Starter Web
- Spring Boot Starter Data JPA
- H2 Database
2. Adding configuration files
Create three files:
application.yml— the main configuration file.application-dev.yml— settings for development.application-prod.yml— settings for production.
application.yml
spring:
profiles:
active: dev
application-dev.yml
app:
name: MyApp (Dev)
server:
port: 8080
datasource:
url: jdbc:h2:mem:devdb
username: dev_user
password: password
application-prod.yml
app:
name: MyApp (Prod)
server:
port: 8081
datasource:
url: jdbc:mysql://prod.server:3306/proddb
username: prod_user
password: prod_password
3. Using profiles in code
Let's create a controller that returns the current application name.
AppController.java
@RestController
@RequestMapping("/api")
public class AppController {
@Value("${app.name}")
private String appName;
@GetMapping("/name")
public String getAppName() {
return appName; // Return the application name specified in configuration
}
}
4. Running the application
5. Start the app with the dev profile:
java -jar myapp.jar --spring.profiles.active=dev
Open http://localhost:8080/api/name. You should see:
MyApp (Dev)
6. Start the app with the prod profile:
java -jar myapp.jar --spring.profiles.active=prod
Open http://localhost:8081/api/name. Result:
MyApp (Prod)
Best practice: working with profiles in a large project
- Create minimal default settings. For example, keep common parameters in
application.ymland profile-specific ones in the profiled files. - Don't hardcode production passwords in the code. Use secrets for that (for example HashiCorp Vault).
- Add a test profile. That will make testing your app easier.
Example: application.yml
logging:
level: INFO
application-test.yml
logging:
level: DEBUG
datasource:
url: jdbc:h2:mem:testdb
What to do if something goes wrong?
Beginners often forget to activate a profile. That causes Spring to use the default configuration (application.yml). To avoid this:
- Always set the profile explicitly using the
spring.profiles.activeparameter. - Check the console logs — Spring always indicates which profile is active.
Another issue is overlapping settings. If you set the same parameters in multiple files, Spring will give priority to the active profile. It's easy to forget, but as you know, logging is your best friend.
The official Spring documentation on profiles will help you dive deeper.
GO TO FULL VERSION