Spring Boot Profiles

Complete Beginner-Friendly Chapter — Run Different Configuration and Beans in Different Environments
Big idea: Spring Profiles let you separate parts of application configuration and make them available only in selected environments. For example, you can have dev, qa, and production behavior without changing your Java code every time.
Interview point: Profiles are very important for Spring Boot interviews. You should understand @Profile, spring.profiles.active, spring.profiles.default, spring.profiles.include, profile groups, profile-specific files, and property precedence.

1. What is a Spring Profile?

A profile is a named environment or configuration mode.

dev qa staging production

For example:

  • dev → local database
  • qa → QA database
  • production → production database

The same Spring Boot application can activate different profiles depending on where it is running.

2. Why Do We Need Profiles?

Imagine this application:

EnvironmentDatabaseLoggingExternal API
DevelopmentlocalhostDEBUGSandbox
QAQA DBINFOQA API
ProductionProduction DBWARN/INFOProduction API

Without profiles, developers often end up changing configuration manually before each deployment.

Profiles solve this: one codebase → multiple environment configurations.

3. The @Profile Annotation

You can mark a @Component, @Configuration, or @ConfigurationProperties with @Profile to control when it is loaded.

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration(proxyBeanMethods = false)
@Profile("production")
public class ProductionConfiguration {

    // Production-only configuration
}

This configuration is loaded only when the production profile is active.

Simple mental model

@Profile("production") + production active Bean loaded

If production is not active, this configuration is not loaded.

4. @Profile on Components

You can use profiles on regular Spring components as well.

@Component
@Profile("dev")
public class DevEmailService implements EmailService {

    @Override
    public void send(String message) {
        System.out.println("DEV EMAIL: " + message);
    }
}
@Component
@Profile("production")
public class ProductionEmailService implements EmailService {

    @Override
    public void send(String message) {
        // Send a real email
    }
}

Now:

Active profileBean available
devDevEmailService
productionProductionEmailService

5. @Profile on @Configuration

A very common pattern is to put several related beans inside a profile-specific configuration class.

@Configuration
@Profile("dev")
public class DevConfig {

    @Bean
    public PaymentClient paymentClient() {
        return new FakePaymentClient();
    }

    @Bean
    public EmailClient emailClient() {
        return new ConsoleEmailClient();
    }
}
@Configuration
@Profile("production")
public class ProductionConfig {

    @Bean
    public PaymentClient paymentClient() {
        return new RealPaymentClient();
    }

    @Bean
    public EmailClient emailClient() {
        return new RealEmailClient();
    }
}
Real-world use: Development can use fake implementations while production uses real external services.

6. Activating a Profile

Spring Boot uses the spring.profiles.active property to specify active profiles.

application.properties

spring.profiles.active=dev

application.yaml

spring:
  profiles:
    active: "dev"

Command line

java -jar app.jar --spring.profiles.active=dev

You can activate more than one profile:

spring.profiles.active=dev,hsqldb

This means both dev and hsqldb are active.

7. Command Line Can Override application.properties

Suppose your file contains:

spring.profiles.active=dev

But you start the application with:

java -jar app.jar --spring.profiles.active=production

The command-line value wins because spring.profiles.active follows the normal property-source ordering rules. The highest-precedence source wins.

Easy rule: A profile declared in application.properties can be replaced by a higher-precedence source such as the command line.

8. Default Profile

If no profile is active, Spring Boot enables a default profile.

The default profile name is:

default

You can change it:

spring.profiles.default=local

Now, when no explicit profile is active, local becomes the default profile.

Disable the default profile

spring.profiles.default=none

This means no default profile is automatically activated.

9. Active vs Default Profile

PropertyMeaning
spring.profiles.activeExplicitly chooses profiles to activate.
spring.profiles.defaultDefines what profile is used when no profile is active.
Example:
If spring.profiles.active=prod, then prod is active.
If spring.profiles.active is absent, Spring Boot uses the default profile, which is default unless changed.

10. Important Rule: Where active/default Can Be Used

spring.profiles.active and spring.profiles.default can only be used in non-profile-specific documents. They cannot be placed inside profile-specific files or documents activated using spring.config.activate.on-profile.

Invalid idea: Do not put spring.profiles.active inside application-prod.properties or inside a YAML document activated by spring.config.activate.on-profile.

Invalid example

spring.profiles.active=prod

#---

spring.config.activate.on-profile=prod
spring.profiles.active=metrics

The second document is invalid because it attempts to activate profiles from a profile-activated document.

11. Profile-Specific Configuration Files

You can create separate configuration files for each profile.

application.properties
application-dev.properties
application-qa.properties
application-prod.properties

Example base configuration:

spring.application.name=my-api
server.port=8080

app.message=Default message

Development:

app.message=Development message
app.database-url=jdbc:postgresql://localhost/dev

Production:

app.message=Production message
app.database-url=jdbc:postgresql://prod-db/myapp

12. How Profile-Specific Files Work

Suppose:

application.properties
application-prod.properties

And:

spring.profiles.active=prod
application.properties + application-prod.properties Final configuration

Properties from the profile-specific configuration can override corresponding values from the base configuration.

13. Multiple Active Profiles

You can activate multiple profiles:

spring.profiles.active=prod,metrics

This can be useful when profiles represent separate concerns.

Example:
prod → production behavior
metrics → monitoring behavior

Both can be active together.

14. Adding Profiles Instead of Replacing Them

Sometimes you do not want to replace active profiles. You want to add more profiles.

Use:

spring.profiles.include[0]=common
spring.profiles.include[1]=local

YAML:

spring:
  profiles:
    include:
      - "common"
      - "local"

Included profiles are added before the profiles activated by spring.profiles.active.

15. active vs include

PropertyWhat it does
spring.profiles.activeDefines the active profiles.
spring.profiles.includeAdds additional profiles on top of active profiles.

Example

spring.profiles.active=production

spring.profiles.include[0]=common
spring.profiles.include[1]=metrics

The effective profile set includes:

common metrics production
spring.profiles.include is processed for each property source, so normal complex-type list merging rules do not apply.

16. include Has the Same Placement Rule

Like spring.profiles.active, spring.profiles.include can only be used in non-profile-specific documents.

Do not put spring.profiles.include inside a profile-specific file or a document activated by spring.config.activate.on-profile.

17. Profile Groups

Sometimes profiles become too fine-grained.

For example:

  • proddb → production database
  • prodmq → production messaging

Instead of activating both manually, create a profile group:

spring.profiles.group.production[0]=proddb
spring.profiles.group.production[1]=prodmq

YAML:

spring:
  profiles:
    group:
      production:
        - "proddb"
        - "prodmq"

18. Why Profile Groups Are Useful

Now you can simply run:

java -jar app.jar --spring.profiles.active=production

and Spring Boot activates:

production proddb prodmq
Easy memory: A profile group is a shortcut name for a related set of profiles.

19. Profile Groups Example

spring:
  profiles:
    group:
      production:
        - proddb
        - prodmq
      development:
        - devdb
        - devtools

Now:

Active profileProfiles activated
productionproduction + proddb + prodmq
developmentdevelopment + devdb + devtools

20. Profile Groups Placement Rule

spring.profiles.group can only be used in non-profile-specific documents. It cannot be defined inside a profile-specific file or a document activated by spring.config.activate.on-profile.

21. Programmatically Setting Profiles

You can programmatically add profiles before the application runs.

SpringApplication application =
        new SpringApplication(MyApplication.class);

application.setAdditionalProfiles("metrics", "local");

application.run(args);

The official documentation also notes that profiles can be activated through Spring's ConfigurableEnvironment interface.

22. @Profile with ConfigurationProperties

@ConfigurationProperties has a specific profile-related rule.

If configuration properties are scanned automatically, @Profile can be placed directly on the @ConfigurationProperties class.

@ConfigurationProperties("app")
@Profile("production")
public class ProductionProperties {

    // ...
}

But if the properties bean is registered through @EnableConfigurationProperties, put @Profile on the configuration class containing @EnableConfigurationProperties.

Example with @EnableConfigurationProperties

@Configuration
@Profile("production")
@EnableConfigurationProperties(ProductionProperties.class)
public class ProductionConfig {
}
Do not automatically assume @Profile belongs on the properties class in every registration style. The placement depends on how the @ConfigurationProperties bean is registered.

23. Profile Validation

Spring Boot validates profile names by default.

Permitted profile names can contain letters, numbers, and characters such as:

- _ . + @

They must start and end with a letter or number.

If you need more flexible profile names, you can disable validation:

spring.profiles.validate=false

YAML:

spring:
  profiles:
    validate: false

This behavior is documented in the current Spring Boot Profiles documentation.

24. Profile Files vs @Profile

These two concepts are related but different.

FeaturePurposeExample
Profile-specific fileChange property values by environment.application-prod.properties
@ProfileChoose which beans/configuration classes are created.@Profile("prod")
Think:
Profile file = configuration values
@Profile = which beans/configuration exist

25. Dev / QA / Production Example

application.properties

spring.application.name=my-api
app.timeout=30s

application-dev.properties

app.database-url=jdbc:postgresql://localhost/dev
app.logging-level=DEBUG

application-qa.properties

app.database-url=jdbc:postgresql://qa-db/myapp
app.logging-level=INFO

application-prod.properties

app.database-url=jdbc:postgresql://prod-db/myapp
app.logging-level=WARN

Run development:

java -jar app.jar --spring.profiles.active=dev

Run QA:

java -jar app.jar --spring.profiles.active=qa

Run production:

java -jar app.jar --spring.profiles.active=prod

26. Real-World Bean Switching

Suppose your application sends notifications.

Development

@Component
@Profile("dev")
public class ConsoleNotificationService
        implements NotificationService {

    public void send(String message) {
        System.out.println(message);
    }
}

Production

@Component
@Profile("prod")
public class EmailNotificationService
        implements NotificationService {

    public void send(String message) {
        // Send real email
    }
}

Now the application can use the same interface while the implementation changes according to the active profile.

27. Combining Profiles with Externalized Configuration

Profiles become especially powerful when combined with externalized configuration.

Base properties + Profile properties + Environment variables + CLI overrides Final Environment

For example:

application.properties
application-prod.properties
Environment variable
Command-line argument

The final value is determined by Spring Boot's property-source precedence rules.

28. Common Mistakes

MistakeCorrect understanding
Putting spring.profiles.active inside application-prod.properties.Active/default profile properties belong in non-profile-specific documents.
Thinking include replaces active profiles.include adds profiles.
Manually activating every fine-grained profile.Use a profile group.
Using a profile only for property values when bean implementations must change.Use @Profile on components/configuration.
Assuming the default profile runs even when another profile is active.The default profile is used when no profile is active.
Ignoring property precedence.Higher-precedence sources can replace active profile configuration.
Putting @Profile on the wrong configuration-properties registration point.Placement depends on whether scanning or @EnableConfigurationProperties is used.

29. Best Practices

  1. Use clear names: dev, qa, staging, prod.
  2. Keep common configuration in the base file.
  3. Put environment-specific values in profile-specific files.
  4. Use @Profile when bean implementations should change.
  5. Use profile groups when multiple low-level profiles always travel together.
  6. Use include when common additional profiles should always be added.
  7. Do not put secrets in profile files committed to Git.
  8. Use externalized configuration and environment variables for deployment-specific secrets.
  9. Understand precedence before debugging profile behavior.

30. Quick Decision Guide

RequirementUse
Different property values for dev/prodProfile-specific files
Different bean implementation for dev/prod@Profile
Always add common configurationspring.profiles.include
Group several profiles under one logical namespring.profiles.group
Choose active environmentspring.profiles.active
Choose fallback profilespring.profiles.default
Add profiles from JavasetAdditionalProfiles()
Need custom profile-name syntaxspring.profiles.validate=false

31. Interview Questions

  1. What is a Spring Profile?
  2. Why do we use profiles in Spring Boot?
  3. What does @Profile do?
  4. Where can @Profile be used?
  5. How do you activate a profile?
  6. What is spring.profiles.active?
  7. What happens if no profile is active?
  8. What is spring.profiles.default?
  9. How can you disable the default profile?
  10. Can spring.profiles.active be placed inside a profile-specific file?
  11. What is the difference between active and include?
  12. What is a profile group?
  13. Why would you use spring.profiles.group?
  14. How do you activate profiles programmatically?
  15. What is the difference between application-prod.properties and @Profile("prod")?
  16. How does property precedence affect active profiles?
  17. How does @Profile work with @ConfigurationProperties?
  18. What is profile validation?

32. Practice Exercises

Exercise 1: Create application-dev.properties and application-prod.properties.
Exercise 2: Activate the dev profile from application.properties.
Exercise 3: Override the active profile using the command line.
Exercise 4: Create a @Profile("dev") bean and a @Profile("prod") bean.
Exercise 5: Create a production profile group containing proddb and prodmq.
Exercise 6: Add common and metrics using spring.profiles.include.
Exercise 7: Set the default profile to local.
Exercise 8: Explain why spring.profiles.active cannot be placed inside application-prod.properties.

33. Cheat Sheet

ConceptExample
Activate profilespring.profiles.active=prod
Command-line activation--spring.profiles.active=prod
Default profilespring.profiles.default=local
No default profilespring.profiles.default=none
Add profilesspring.profiles.include
Group profilesspring.profiles.group
Profile-specific propertiesapplication-prod.properties
Profile-specific bean@Profile("prod")
Programmatic profilessetAdditionalProfiles()
Disable profile-name validationspring.profiles.validate=false

34. Memory Map

Profiles @Profile active default include group Profile-specific files Property precedence setAdditionalProfiles()

35. Final Takeaway

Remember this simple logic:

Profile = environment/mode.

spring.profiles.active → Which profiles should run?
spring.profiles.default → Which profile should run if none is active?
spring.profiles.include → Add extra profiles.
spring.profiles.group → Give a logical name to several profiles.
@Profile → Decide which beans/configuration are loaded.
application-prod.properties → Change configuration values for production.
setAdditionalProfiles() → Add profiles programmatically.

Same application + different profiles = different environment behavior.