Conditional Annotations in Spring Boot with Examples

Conditional Annotations in Spring Boot with Examples

Overview

This article will cover the most commonly used Conditional annotations in Spring boot, real-world use cases, and why they are essential for writing clean, modular, and environment-aware applications.

Conditional Annotations in Spring Boot

Introduction to Conditional Annotations in Spring Boot

Spring Boot has become the powerful framework for building production ready Java applications. One of its most powerful features is auto-configuration, which allows the spring framework to automatically configure beans based on the environment, classpath, and application properties.

At the heart of this mechanism are Spring Boot Conditional Annotations. These annotations let you define conditions under which a bean should (or should not) be created.

✅ What are Conditional Annotations in Spring Boot?

Conditional annotations allow you to configure Spring beans dynamically. Instead of loading everything, you can tell Spring Boot to only create beans when certain conditions are met.

For example:

  • A payment service bean should only load if the Razorpay gateway is enabled.
  • A debug logger should only load in non-production environments.
  • A MySQL DataSource should only load if the MySQL driver is available.

This selective bean creation makes your application:

  • Efficient (avoids unnecessary beans)
  • Environment-aware (different setups for dev, test, prod) .
  • Modular (easier to maintain and extend) .

Common Conditional Annotations & Conditional Annotation Examples

1️⃣ @ConditionalOnProperty

Load a bean only if a specific property exists and has a given value.

Use Case: Enable/disable a Payment Gateway integration.


@Bean
@ConditionalOnProperty(
    name = "payment.razorpay.enabled", 
    havingValue = "true"
)
public RazorpayClient razorpayClient() {
    return new RazorpayClient("apiKey", "secret");
}

👉 If payment.razorpay.enabled=true in application.properties, the bean will be created.

2️⃣ @ConditionalOnClass

Create a bean only if a class is present on the classpath.

Use Case: Load MySQL DataSource only if MySQL connector is available.


@Bean
@ConditionalOnClass(name = "com.mysql.cj.jdbc.Driver")
public DataSource mysqlDataSource() {
    return DataSourceBuilder.create()
            .url("jdbc:mysql://localhost:3306/demo")
            .username("root")
            .password("password")
            .build();
}

3️⃣ @ConditionalOnMissingClass

Opposite of @ConditionalOnClass. Loads a bean only if a class is NOT present.

Use Case: Provide an in-memory fallback database if MySQL driver is missing.


@Bean
@ConditionalOnMissingClass("com.mysql.cj.jdbc.Driver")
public DataSource h2DataSource() {
    return DataSourceBuilder.create()
            .url("jdbc:h2:mem:testdb")
            .username("sa")
            .build();
}

4️⃣ @ConditionalOnBean

Create a bean only if another bean exists.

Use Case:Start NotificationService only if EmailService bean is available.


@Bean
@ConditionalOnBean(EmailService.class)
public NotificationService notificationService() {
    return new NotificationService();
}

5️⃣ @ConditionalOnMissingBean

Load a bean only if another bean is not defined.

Use Case: Provide a default RestTemplate if the user hasn’t defined one.


@Bean
@ConditionalOnMissingBean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

6️⃣ @ConditionalOnExpression

Use Spring Expression Language (SpEL) to define conditions.

Use Case: Enable debug logging in non-production environments.


@Bean
@ConditionalOnExpression("!'prod'.equals('${spring.profiles.active}')" )
public DebugLogger debugLogger() {
    return new DebugLogger();
}

7️⃣ @ConditionalOnResource

Create a bean if a specific resource (like a file or config) exists.

Use Case: Load custom theme only if theme.css exists.


@Bean
@ConditionalOnResource(resources = "classpath:theme.css")
public ThemeLoader themeLoader() {
    return new ThemeLoader();
}

8️⃣ @ConditionalOnJava

Load a bean based on the Java version.

Use Case: Enable features that require Java 17.


@Bean
@ConditionalOnJava(JavaVersion.SEVENTEEN)
public ModernFeature modernFeature() {
    return new ModernFeature();
}

9️⃣ @ConditionalOnWebApplication

Create a bean only in a web application context.

Use Case: Enable CORS configuration only in web apps.


@Bean
@ConditionalOnWebApplication
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {

        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("*");
        }
    };
}

🔟 @ConditionalOnNotWebApplication

Opposite of @ConditionalOnWebApplication. Loads only in a non-web context.

Use Case: Run batch processing jobs in a non-web app.


@Bean
@ConditionalOnNotWebApplication
public BatchJobScheduler batchJobScheduler() {
    return new BatchJobScheduler();
}

Why Conditional Annotations Matter

  • Environment-aware apps – Load only what’s needed in dev, test, prod.
  • Optimized performance – Avoids unnecessary beans in memory.
  • Cleaner code – Makes auto-configuration modular and flexible.
  • Foundation of Spring Boot starters – This is exactly how spring-boot-starter-* libraries work!

Conclusion

Spring Boot Conditional Annotations in the Spring Framework give developers fine-grained control over bean definition and creation. By using them smartly in a configuration class, you can implement flexible logic, override defaults, or even disable auto-configured beans under certain conditions.

Whether you want to enable or disable beans using @ConditionalOnProperty, check the classpath, or write a custom condition with AnnotatedTypeMetadata metadata, these annotations let you annotate and fine-tune behavior at runtime.

This metadata-driven approach ensures that your applications in Java remain modular, optimized, and adaptable—no matter the environment. So, the next time you see Spring Boot magically configuring beans, remember: it’s powered by these powerful conditional annotations

Leave a Comment