Chapter 2.6☕ 14 min read

Spring Profiles

Same JAR, different configs. Profiles make it possible.

01The Concept: Environment Switching

The Dress Code Analogy:

An IT professional's job is the same (writing code). But the dress changes based on the environment:

  • Dev Profile (Work From Home): Pajamas and T-shirt. Loose rules, H2 in-memory database, debug logs on.
  • Prod Profile (Client Meeting): Formal suit. Strict rules, MySQL database, error logs only.

The @Profile annotation tells Spring to activate this Bean or Configuration only when that specific "dress" (environment) is worn.

02Technical Explanation
  1. Create multiple property files: application-dev.properties and application-prod.properties.
  2. Set the active profile in the main application.properties: spring.profiles.active=dev or via environment variable: SPRING_PROFILES_ACTIVE=prod.
  3. Use @Profile("dev") on beans so they only get created in specific environments.

This keeps your codebase clean — no if-else checks for environments pollute your business logic.

03Full Working Code: Profile-Specific Beans
package com.devinhyderabad;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;

@SpringBootApplication
public class Application implements CommandLineRunner {

@Autowired
private DatabaseSetup databaseSetup;

public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setAdditionalProfiles("dev");
app.run(args);
}

@Override
public void run(String... args) throws Exception {
databaseSetup.connect();
}
}

interface DatabaseSetup {
void connect();
}

@Component
@Profile("dev")
class H2DatabaseSetup implements DatabaseSetup {
@Override
public void connect() {
System.out.println("Connected to local H2 In-Memory DB. Fast!");
}
}

@Component
@Profile("prod")
class MySQLDatabaseSetup implements DatabaseSetup {
@Override
public void connect() {
System.out.println("Connected to Production MySQL. Secure!");
}
}
04Code: H2 vs MySQL Setup

When app.setAdditionalProfiles("dev") is used, Spring only creates H2DatabaseSetup. The MySQLDatabaseSetup bean is never created. Change it to "prod", and H2DatabaseSetup vanishes while MySQLDatabaseSetup takes over!

In real production, you never hardcode the profile. You set it via environment variable in your deployment platform (AWS, Kubernetes, Docker): SPRING_PROFILES_ACTIVE=prod.

05Why It Matters / Interview Note

Interview Question: "How do you manage different configurations across different environments without changing code?"

Answer: "We use Spring Profiles. We create separate property files like application-dev.yml and application-prod.yml. On the server, we set SPRING_PROFILES_ACTIVE=prod as an environment variable. Spring reads this and loads only the matching profile's properties. Beans annotated with @Profile("prod") only spin up in production."

Enterprise Note: In cloud environments like AWS or Kubernetes, the exact same Docker JAR image is deployed everywhere. The only difference is the environment variable injected by the cloud platform telling Spring which profile to activate.

Key Takeaways

  • ✅ Spring Profiles allow different configs for different environments
  • ✅ Use @Profile("dev") on beans to control which environments create them
  • ✅ Set active profile via application.properties or SPRING_PROFILES_ACTIVE env var
  • ✅ Same JAR deployed everywhere — only the profile env var changes