Clean ⢠Professional
In Spring and Spring Boot, @Profile-based beans are beans that are created only when a specific Spring profile is active.
In simple words:
@Profile = Load this bean only for a specific environment
Profiles help Spring decide which beans to load and which to ignore at application startup.
Different environments need different configurations.
Real-World Environments
| Environment | Typical Requirements |
|---|---|
| dev | H2 DB, mock APIs, debug logging |
| test | Test DB, test configurations |
| qa | Near-production setup |
| prod | MySQL/PostgreSQL, real APIs, security |
A Spring Profile is a named logical group of beans.
dev, test, qa, prod, default
If @Profile is not used, the bean is created in all environments.
@Component
publicclassEmailService {
}
ā Always loaded
ā No environment control
@Profile on a Bean (Class Level)The @Profile annotation can be applied directly on a bean class to control when the bean should be created based on the active Spring profile.
Example
@Component
@Profile("dev")
publicclassDevEmailService {
}
dev profiledev profile is active| Active Profile | DevEmailService Created |
|---|---|
dev | Yes |
prod | No |
test | No |
| none (default) | No |
@ProfileA common and recommended use of @Profile is to provide different implementations of the same interface for different environments.
This approach avoids if-else logic, keeps the code clean, and follows SOLID principles.
publicinterfacePaymentService {
voidpay();
}
@Service
@Profile("dev")
publicclassDevPaymentServiceimplementsPaymentService {
@Override
publicvoidpay() {
System.out.println("Dev payment processing");
}
}
dev profile is active@Service
@Profile("prod")
publicclassProdPaymentServiceimplementsPaymentService {
@Override
publicvoidpay() {
System.out.println("Prod payment processing");
}
}
prod profile is active| Active Profile | Loaded Bean |
|---|---|
dev | DevPaymentService |
prod | ProdPaymentService |
Spring automatically injects the correct implementation.
if-else or profile checks in business code@Service
publicclassOrderService {
privatefinal PaymentService paymentService;
publicOrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
publicvoidplaceOrder() {
paymentService.pay();
}
}
dev or prod@Profile with @Configuration and @BeanThe @Profile annotation can also be used on @Bean methods inside a @Configuration class.
This is commonly used for environment-specific infrastructure beans, such as databases.
Example
@Configuration
publicclassAppConfig {
@Bean
@Profile("dev")
public DataSourcedevDataSource() {
returnnewH2DataSource();
}
@Bean
@Profile("prod")
public DataSourceprodDataSource() {
returnnewMySQLDataSource();
}
}
dev
devDataSource() is executedDataSource bean is createdprod
prodDataSource() is executedDataSource bean is createdSpring profiles must be explicitly activated so that Spring knows which beans and configurations to load.
application.propertiesspring.profiles.active=dev
dev profileapplication-dev.properties
application-prod.properties
dev ā application-dev.propertiesprod ā application-prod.propertiesapplication.propertiesjava -jar app.jar --spring.profiles.active=prodSPRING_PROFILES_ACTIVE=prod
application.propertiesSpring allows multiple profiles to be active at the same time.
This is useful when your application needs combined configurations (e.g., environment + cloud).
spring.profiles.active=dev,clouddev and cloud profiles are active@Component
@Profile({"dev", "cloud"})
publicclassCloudDevService {
}!) Profile ConditionSpring allows you to exclude a profile using the ! (NOT) operator in @Profile.
This means the bean will be created for all profiles except the specified one.
Example
@Component
@Profile("!prod")
publicclassNonProdLogger {
}prod ā bean is NOT createdIf no profile is set, Spring uses default.
@Component
@Profile("default")
publicclassDefaultService {
}ā Loaded only when no profile is active
When a Spring profile is active, Spring loads configuration files in a fixed and predictable order.
Example: Active Profile = dev
application.propertiesapplication-dev.properties (overrides default values)Profile groups allow you to activate multiple related profiles using a single name.
Example
spring.profiles.group.dev=dev,cloud,debug
spring.profiles.group.prod=prod,security
spring.profiles.active=devdev automatically activates:
devclouddebug@Profile in TestsSpring allows activating profiles only for test execution.
Example
@SpringBootTest
@ActiveProfiles("test")
publicclassPaymentServiceTest {
}Behavior
@Profile("test") are loadedā Essential for JUnit and integration testing
@Profile with @LazyYou can combine @Profile with @Lazy for environment-based and on-demand initialization.
Example
@Component
@Profile("prod")
@Lazy
publicclassHeavyProdService {
}Behavior
prod profileā Best for heavy, optional production components
@Profile vs @ConditionalOnProperty (Real Use Cases)Spring provides multiple ways to conditionally create beans, but @Profile and @ConditionalOnProperty are commonly used for different purposes.
| Feature | @Profile | @ConditionalOnProperty |
|---|---|---|
| Based on | Environment (dev/test/prod) | Property value (application.properties / env) |
| Best for | Selecting environment-specific beans | Feature flags, optional features |
| Flexibility | Medium | High |
| Activation | Startup profile | Property values, can enable/disable features dynamically |
| Typical Use Case | dev vs prod services | feature.payment.enabled=true |
Example: @ConditionalOnProperty
@Component
@ConditionalOnProperty(
name = "feature.payment.enabled",
havingValue = "true"
)
publicclassPaymentService {
publicPaymentService() {
System.out.println("PaymentService created!");
}
}feature.payment.enabled=true@Profile for environment-specific beans
dev database vs prod database@ConditionalOnProperty for feature flags
Spring Boot automatically configures beans based on:
application.properties or application-<profile>.propertiesprod ā Real database auto-configurationdev ā Embedded database auto-configuration| Environment | Services |
|---|---|
| dev | Local + mock services |
| qa | Staging services |
| prod | Real services |
spring.profiles.active@Profile-based beans allow Spring applications to load only the beans required for a specific environment.
They help you: