Spring Boot - Profiles

Spring Profiles provide a way to segregate configuration so that it is only active in certain environments. You can define profile-specific property files, conditionally register beans with @Profile, and switch environments at startup without changing source code.

Contents

Profile-specific property files

Spring Boot automatically loads application-{profile}.properties on top of the base application.properties. Profile-specific values override base values.

Text
src/main/resources/
  application.properties          ← shared / base config
  application-dev.properties      ← development overrides
  application-test.properties     ← test environment
  application-prod.properties     ← production overrides

application-dev.properties:

Properties
spring.datasource.url=jdbc:h2:mem:devdb
spring.jpa.hibernate.ddl-auto=create-drop
logging.level.io.cscode=DEBUG

application-prod.properties:

Properties
spring.datasource.url=jdbc:postgresql://prod-db-host:5432/mydb
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASS}
spring.jpa.hibernate.ddl-auto=validate

Activating a profile

1. In application.properties (useful for local dev):

Properties
spring.profiles.active=dev

2. JVM system property (common in CI scripts):

Shell
java -Dspring.profiles.active=prod -jar myapp.jar

3. Environment variable (Kubernetes, Docker, cloud platforms):

Shell
SPRING_PROFILES_ACTIVE=prod java -jar myapp.jar

@Profile on beans and configurations

Use @Profile to register a bean only when a specific profile is active: ideal for swapping implementations between environments.

Java
public interface NotificationService {
    void send(String message);
}
Java
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile("dev")     // only active in 'dev' profile
public class ConsoleNotificationService implements NotificationService {

    @Override
    public void send(String message) {
        System.out.println("[DEV] " + message);
    }
}
Java
@Service
@Profile("prod")    // only active in 'prod' profile
public class EmailNotificationService implements NotificationService {

    @Override
    public void send(String message) {
        // send real email via SMTP / SES
    }
}

You can also negate a profile: @Profile("!prod") activates the bean for every profile except prod.

Default profile

Beans annotated with @Profile("default") are active only when no other profile is active: a safe fallback for local development.

Java
@Service
@Profile("default")
public class StubPaymentService implements PaymentService {

    @Override
    public void charge(Order order) {
        System.out.println("Stub: charged order " + order.getId());
    }
}