Backend Development 25 min read

Understanding Conditional Configuration and Profiles in Spring Framework

This article explains Spring's conditional configuration features—including @Profile, @Conditional, and various @ConditionalOn* annotations—showing how to dynamically register beans based on environment, classpath, properties, or other bean presence, with detailed code examples and usage guidelines.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding Conditional Configuration and Profiles in Spring Framework

Spring's conditional configuration (Conditional Configuration) allows beans to be registered or created only when specific conditions are met, enabling modular and environment‑specific applications.

Key annotations provided by Spring include:

@Profile : activates beans only when a particular profile is active.

@Conditional : uses custom Condition implementations to decide bean creation.

Spring Boot adds a set of specialized annotations for automatic configuration:

@ConditionalOnProperty : creates a bean when a configuration property has a given value.

@ConditionalOnClass / @ConditionalOnMissingClass : checks for the presence or absence of a class on the classpath.

@ConditionalOnBean / @ConditionalOnMissingBean : creates a bean based on the existence of another bean.

Example of @Profile with multiple data sources

package com.example.demo.configuration;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.boot.jdbc.DataSourceBuilder;
import javax.sql.DataSource;

@Configuration
public class DataSourceConfiguration {
    @Value("${spring.datasource.username}") private String username;
    @Value("${spring.datasource.password}") private String password;
    @Value("${spring.datasource.url}") private String url;

    @Bean
    @Profile("dev")
    public DataSource devDataSource() {
        return DataSourceBuilder.create()
            .username(username)
            .password(password)
            .url(url + "?useSSL=false&serverTimezone=Asia/Shanghai")
            .driverClassName("com.mysql.cj.jdbc.Driver")
            .build();
    }

    @Bean
    @Profile("test")
    public DataSource testDataSource() { /* similar to dev */ }

    @Bean
    @Profile("prod")
    public DataSource prodDataSource() { /* similar with SSL enabled */ }
}

The example demonstrates how different profiles ( dev , test , prod ) can load distinct database configurations.

Determining the active profile

Spring resolves the active profile using the following precedence (high to low):

Programmatic call ConfigurableEnvironment.setActiveProfiles

JVM argument -Dspring.profiles.active or environment variable SPRING_PROFILES_ACTIVE (Spring Boot only)

SpringApplicationBuilder.profiles (Spring Boot only)

SpringApplication.setDefaultProperties (Spring Boot only)

Property spring.profiles.active in configuration files

Only the highest‑priority setting takes effect.

Example using programmatic activation:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("weekday");
context.register(WeekdayLibraryConfiguration.class);
context.refresh();

Running the application prints the beans created for the selected profile.

@Conditional example

A custom condition can check for the existence of another bean before creating a dependent bean.

package com.example.demo.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class LibrarianCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getBeanFactory().containsBeanDefinition("librarian");
    }
}

Configuration using the condition:

package com.example.demo.configuration;

import com.example.demo.bean.Library;
import com.example.demo.bean.Librarian;
import com.example.demo.condition.LibrarianCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LibraryConfiguration {
    @Bean
    public Librarian librarian() { return new Librarian(); }

    @Bean
    @Conditional(LibrarianCondition.class)
    public Library library() { return new Library("The Great Library"); }
}

When the Librarian bean is present, the Library bean is created; otherwise it is omitted.

Spring Boot specific @ConditionalOn* annotations

Using @ConditionalOnBean simplifies the previous example:

@Bean
@ConditionalOnBean(Librarian.class)
public Library library() { return new Library("The Great Library"); }

Similarly, @ConditionalOnProperty can enable beans based on configuration properties:

@Configuration
public class MyConfiguration {
    @Bean
    @ConditionalOnProperty(name = "my.feature.enabled", havingValue = "true", matchIfMissing = true)
    public MyFeature myFeature() { return new MyFeature(); }
}

And @ConditionalOnClass / @ConditionalOnMissingClass control bean creation depending on classpath availability.

Overall, Spring's conditional annotations provide powerful mechanisms for building flexible, environment‑aware backend applications.

JavaBackend DevelopmentSpringdependency injectionProfilesConditional Configuration
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.