@Profile Annotation in Spring Explained
Fast recall
Quick revision
Core answer
Profile-based configuration knowledge and environment-specific bean creation
Confusing @Profile on beans with profile-specific properties files like application-dev.properties
Give a concrete example of different DataSource implementations per profile and explain profile activation methods
Interview-ready guide
Interview answer
A LocalMailConfig can provide a logging MailSender under @Profile("dev"), while a production integration is active under @Profile("prod"). In many cases it is simpler to keep one auto-configured DataSource and change only URL/credentials through application-dev.properties and application-prod.properties rather than hand-writing profile DataSource beans. Profiles decide which definitions exist; config data supplies their values.
@Profile Annotation in Spring Explained
Direct Answer
@Profile makes a component or @Bean definition active only when a profile expression matches the Environment's active profiles. @Profile("dev") enables it for dev; @Profile("!prod") matches when prod is not active. Profiles select bean/configuration variants at context creation. Profile-specific config files change values and are related, but they are not the same mechanism.
Code Example
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev") // Only created when dev profile is active
public DataSource devDataSource() {
var ds = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.build();
System.out.println("Using H2 in-memory database for dev");
return ds;
}
@Bean
@Profile("prod") // Only created when prod profile is active
public DataSource prodDataSource() {
var ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:postgresql://prod-db.example.com:5432/appdb");
ds.setUsername("produser");
ds.setPassword(System.getenv("DB_PASSWORD")); // From environment variable
ds.setMaximumPoolSize(20);
System.out.println("Using PostgreSQL production database");
return ds;
}
@Bean
@Profile("test") // Only for integration tests
public DataSource testDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build();
}
}
Common Mistakes & Pitfalls
- Confusing @Profile with profile-specific properties: Freshers think @Profile("dev") and application-dev.properties are the same. They're complementary. Profile-specific properties change configuration values. @Profile changes which beans exist. Use properties for values, @Profile for implementations.
- No default profile: If you mark all DataSource beans with @Profile and forget to activate a profile, Spring has no DataSource and the app crashes. Always provide a @Profile("default") bean or use @Profile("!prod") to mean "anything except prod".
- Hardcoding profile checks: Freshers write if (activeProfile.equals("dev")) instead of using @Profile. This scatters environment logic everywhere. Let Spring handle it declaratively.
- Not testing profile activation: In production, you set spring.profiles.active=prod via environment variable or command-line. Freshers forget to test this and deploy without activating the right profile, causing the app to use the wrong database.
Check your understanding
Answer these without looking back at the article.
- How does @Profile differ from application-dev.properties?
- How do you combine multiple profiles?
- Can @Profile be used on @Component classes?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.