Mastering Spring Boot’s @Conditional: Dynamically Load Beans Based on Conditions

This guide explains the purpose and mechanics of Spring Boot's @Conditional annotation, shows its source definition, outlines usage forms, provides a complete example with custom Condition implementations for MySQL and Oracle beans, and lists the related derived conditional annotations available in Spring Boot.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Mastering Spring Boot’s @Conditional: Dynamically Load Beans Based on Conditions

Conditional Annotation @Conditional

@Conditional is a Spring Framework annotation (package org.springframework.context.annotation) that determines whether a class or method should be instantiated as a Bean based on one or more Condition implementations. It is heavily used in Spring Boot auto‑configuration to enable beans only when specific criteria are met, such as the presence of a class on the classpath.

Source Code Overview

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {
    // ...
}

Usage Forms

Type level – can be placed on @Component or @Configuration classes.

Prototype level – used on meta‑annotations such as @ConditionalOnClass.

Method level – can annotate any @Bean method.

Note: @Conditional is not inherited; a subclass does not inherit conditions defined on its parent class.

Source Definition of @Conditional

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    // The attribute receives an array of classes that implement Condition
    Class<? extends Condition>[] value();
}

The associated Condition interface defines a single method:

@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

If matches returns true, the annotated component is instantiated; otherwise it is skipped.

Practical Example

We demonstrate a scenario where a configuration property db.type determines which database‑specific bean is created.

db.type=mysql

Two Condition implementations read this property:

public class MysqlCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String dbType = context.getEnvironment().getProperty("db.type");
        return "mysql".equalsIgnoreCase(dbType);
    }
}
public class OracleCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String dbType = context.getEnvironment().getProperty("db.type");
        return "oracle".equalsIgnoreCase(dbType);
    }
}

Both conditions produce beans that implement a common interface:

public interface DbConfigBean {
    void printInfo();
}
public class MysqlDbConfigBean implements DbConfigBean {
    @Override
    public void printInfo() {
        System.out.println("I am Mysql!");
    }
}
public class OracleDbConfigBean implements DbConfigBean {
    @Override
    public void printInfo() {
        System.out.println("I am Oracle!");
    }
}

The configuration class uses @Conditional on each @Bean method:

@Configuration
public class DbConfig {
    @Bean
    @Conditional(MysqlCondition.class)
    public DbConfigBean mysql() {
        return new MysqlDbConfigBean();
    }

    @Bean
    @Conditional(OracleCondition.class)
    public DbConfigBean oracle() {
        return new OracleDbConfigBean();
    }
}

If both beans could exist simultaneously, the @Primary annotation would be needed to resolve ambiguity.

Service usage:

@Service
public class DbService {
    @Autowired
    private DbConfigBean configBean;

    public void getDbInfo() {
        configBean.printInfo();
    }
}

Unit test example:

@SpringBootTest
class DbServiceTest {
    @Resource
    private DbService dbService;

    @Test
    void getDbInfo() {
        dbService.getDbInfo();
    }
}

Depending on the value of db.type, the appropriate bean prints its message.

Derived Conditional Annotations in Spring Boot

@ConditionalOnBean

– active when a specific bean is present. @ConditionalOnClass – active when a class is on the classpath. @ConditionalOnCloudPlatform – active when a particular cloud platform is active. @ConditionalOnExpression – evaluates a SpEL expression. @ConditionalOnJava – checks the JVM version. @ConditionalOnJndi – looks up a JNDI location. @ConditionalOnMissingBean – active when a bean is absent. @ConditionalOnMissingClass – active when a class is missing. @ConditionalOnNotWebApplication – active for non‑web applications. @ConditionalOnProperty – active when a configuration property has a specific value. @ConditionalOnResource – active when a resource exists on the classpath. @ConditionalOnSingleCandidate – active when a single candidate bean is present or a primary bean is designated. @ConditionalOnWebApplication – active for web applications.

All these meta‑annotations reside in the org.springframework.boot.autoconfigure.condition package of the spring-boot-autoconfigure JAR.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaSpring BootbeanConditional
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

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.