Spring Profiles separate configuration settings and manage bean lifecycles per environment. They work by loading profile-specific application-{profile} files and conditionally instantiating beans annotated with @Profile("{profile}"). Profiles can be activated via the spring.profiles.active property, environment variables, or command-line parameters."
1. Core Concept: What Do Profiles Control?
Spring Boot Profiles primarily impact two main components:
- Configuration Files (Properties/YAML): Determines which configuration files are loaded into the environment.
- Spring Beans: Controls which Beans are created by the IoC container based on
@Profileannotations.
2. Organizing Configuration Files by Profile
Option 1: Separate Files (Most Common).
Standard file naming pattern: application-{profile}.properties or application-{profile}.yml
application.properties(Contains shared configurations common to all environments)application-dev.properties(DEV-specific configuration: Local/H2 DB, DEBUG log level)application-prod.properties(PROD-specific configuration: PostgreSQL Cluster DB, ERROR log level)
Option 2: Single Multi-Document YAML File (Using ---)
spring:
application:
name: my-app
---
spring:
config:
activate:
on-profile: dev
server:
port: 8080
---
spring:
config:
activate:
on-profile: prod
server:
port: 80
3. Applying Profiles to Beans with @Profile
You can attach @Profile to any @Component, @Service, @Repository, or @Configuration class/method. The bean will only be instantiated by the IoC Container if the matching profile is currently active.
public interface EmailService {
void sendEmail(String to, String body);
}
// Only created in DEV or TEST profiles
@Service
@Profile({"dev", "test"})
public class MockEmailService implements EmailService {
@Override
public void sendEmail(String to, String body) {
System.out.println("[MOCK EMAIL] Simulating email to: " + to);
}
}
// Only created in PROD profile
@Service
@Profile("prod")
public class SmtpEmailService implements EmailService {
@Override
public void sendEmail(String to, String body) {
// Real production logic connecting to AWS SES or SendGrid
}
}
Profile Conditional Operators:.
@Profile("dev"): Active when the dev profile is active.@Profile("!prod"): Active when the prod profile is NOT active.@Profile({"dev", "staging"}): Active if either dev OR staging is active.@Profile("dev & mysql"): Active only when both dev AND mysql profiles are active simultaneously.
4. How to Activate a Profile
here are several ways to tell Spring Boot which profile to activate. Below are the most common methods ordered by typical usage:
Method 1: Inside application.properties
spring.profiles.active=dev
Method 2: Command Line Argument (When running JAR).
This is the standard approach when deploying applications to servers or Docker/Kubernetes environments:
java -jar myapp.jar --spring.profiles.active=prod
Method 3: Environment Variables
Ideal for CI/CD pipelines and containerized environments:
export SPRING_PROFILES_ACTIVE=prod
java -jar myapp.jar
Method 4: JVM System Property
java -Dspring.profiles.active=staging -jar myapp.jar
5. Property Override Order (Precedence)
When running the application with a specific profile (e.g., prod):
- Spring Boot loads the base
application.propertiesfile first. - Then it loads the profile-specific
application-prod.propertiesfile. - If a configuration key exists in both files, the profile-specific configuration (
application-prod) overrides the base configuration.