Spring Boot profiles

Adapting application behavior across environments without ever touching the code

In any reasonably serious Spring Boot application, one question inevitably arises:

How do you adapt the application’s behavior depending on the environment?

Development, testing, integration, production…
Constraints change, resources change, yet the code remains the same.

Spring’s historical answer to this problem can be summed up in one word: profiles.

Behind files such as application-dev.properties, application-prod.yml, or application-test.properties lies a fundamental mechanism—simple in appearance, yet deeply structuring for any well-designed Spring Boot application.

The problem: one application, multiple contexts

Without profiles, environment management often relies on risky practices:

  • Manually commenting and uncommenting configuration lines.
  • Duplicating configuration files and renaming them at the last minute.
  • Scattering if (env == “prod”) blocks throughout business code.

These approaches work… until they don’t.

Spring established a clear principle very early on:

The code should not know which environment it is running in.

Profiles are the embodiment of this principle.

What is a Spring profile?

A Spring profile is a logical label that allows you to activate or deactivate:

  • configuration files,
  • beans,
  • application behaviors.

A profile does not represent only a technical environment.
It represents an execution context.

Common examples include:

  • dev
  • test
  • prod
  • local
  • integration

The application-xxx.properties files

Spring Boot automatically loads configuration files based on the active profiles.

Naming convention

application.properties
application-dev.properties
application-test.properties
application-prod.properties
  • application.properties contains shared configuration
  • suffixed files override only what differs

Example

# application.properties
spring.application.name=demo-app

# application-dev.properties
spring.datasource.url=jdbc:h2:mem:testdb

# application-prod.properties
spring.datasource.url=jdbc:postgresql://db/prod

The mechanism is simple, readable, and predictable.
That is precisely why it is so powerful.

Activating a profile

Via properties (static configuration)

In your base application.properties file:

spring.profiles.active=dev

Via environment variables (ideal for Docker / Cloud)

This is the recommended method for production.

export SPRING_PROFILES_ACTIVE=prod
java -jar my-app.jar

Via command-line arguments

Convenient for a quick local test.

java -jar my-app.jar --spring.profiles.active=test

Profiles and conditional beans

This is where profiles truly shine. They allow you to condition the very existence of a Java component using the @Profile annotation.

Example: the email sending service

You don’t want to send real emails during development.

public interface EmailService {
void send(String message);
}

@Profile("dev")
@Service
public class MockEmailService implements EmailService {
@Override
public void send(String message) {
System.out.println("[DEV - LOG ONLY] " + message);
}
}

@Profile("prod")
@Service
public class SmtpEmailService implements EmailService {
@Override
public void send(String message) {
// Real SMTP sending logic
}
}

The benefit: the rest of your application injects an EmailService without ever knowing whether it is a mock or the real implementation.

The 3 golden rules for using profiles correctly

  • The default profile must be functional: Configure application.properties so that any developer can clone the project and run it locally without errors.
  • Do not overuse conditional code: If you start putting @Profile on every class, your code will become difficult to test. Favor interfaces instead.
  • Use exclusion wisely: The ! operator is extremely useful.
    @Profile(“!prod”) allows you to enable a debugging tool in all environments except production.

Conclusion

Spring Boot profiles are not just a configuration convenience. They are the tool that guarantees the immutability of your artifact: you build your JAR once, and the profile injected at startup adapts it to its environment.


Spring Boot profiles was originally published in Javarevisited on Medium, where people are continuing the conversation by highlighting and responding to this story.

This post first appeared on Read More