Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Auto-configuration  ›  Lesson

Conditions — The Switches Behind Auto-configuration

Autoconfiguration 14 min@ConditionalOn annotations ask questions at startup about classes, beans and properties, and a bean is created only when all its conditions are true.

Conditions — The Switches Behind Auto-configuration

library-service should send overdue-book reminder emails in production, but developers do not want real emails leaving their laptops. You could wrap the code in if statements, but Spring has a cleaner tool, the same one Boot uses for all its auto-configuration: conditional beans.

The rule

A condition is a question asked at startup; the bean exists only if the answer is yes.

Each @ConditionalOn... annotation asks one question. The common ones:

Annotation The question
@ConditionalOnClass(X.class) Is class X on the classpath?
@ConditionalOnMissingClass("x.Y") Is class Y absent?
@ConditionalOnBean(X.class) Has a bean of type X already been defined?
@ConditionalOnMissingBean(X.class) Is there no bean of type X yet?
@ConditionalOnProperty(...) Does a property have a given value?
@ConditionalOnWebApplication Is this a web app?

Put one on a @Bean method and it guards that bean. Put one on a configuration class and it guards every bean inside. Several conditions on the same element must all be true.

Here is the reminder switch for library-service:

@Configuration
public class ReminderConfig {

    @Bean
    @ConditionalOnProperty(name = "library.reminders.enabled", havingValue = "true")
    public ReminderSender emailReminders(JavaMailSender mail) {
        return new EmailReminderSender(mail);
    }

    @Bean
    @ConditionalOnProperty(name = "library.reminders.enabled", havingValue = "false",
                           matchIfMissing = true)
    public ReminderSender loggingReminders() {
        return new LoggingReminderSender();   // just writes to the log
    }
}

In production, library.reminders.enabled=true creates the email sender. On a laptop the property is absent: the first condition fails, because by default @ConditionalOnProperty treats a missing property as "no", while the second passes thanks to matchIfMissing = true. Exactly one ReminderSender exists in each environment.

A word of care about @ConditionalOnMissingBean: it only sees beans that were registered before it is checked. That is safe in auto-configuration, which always runs after your own configuration. Inside your own classes the registration order is not guaranteed, so prefer property or class conditions there and leave "missing bean" checks to auto-configuration.

The shortcut

Read any conditional bean as a sentence: "Create this bean only if ___." Fill the blank from each annotation and join them with "and".

Reading Boot's Jackson setupStep 1 of 4
  1. The annotations

    A bean has @ConditionalOnClass(ObjectMapper.class) and @ConditionalOnMissingBean.

Drills

Answer fast — trust the rule.

quick drill

Which condition creates a bean only when a library is present?

quick drill

A bean has @ConditionalOnProperty(name = "library.reminders.enabled", havingValue = "true") and the property is not set at all. Is it created?

quick drill

A bean carries both @ConditionalOnClass(DataSource.class) and @ConditionalOnProperty(name = "x", havingValue = "on"). When is it created?

quick drill

Why does @ConditionalOnMissingBean work reliably in Boot's auto-configuration?

Remember

  • A condition is a question asked at startup; the bean exists only if the answer is yes.
  • Read every conditional bean as "create this only if ___ and ___."
  • Trap: a missing property counts as "no" unless you set matchIfMissing = true.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainDesign a feature switch

library-service should publish loan events to a message broker only when library.events.enabled=true and the broker's client library is on the classpath. Describe the conditions you would put on the publisher bean, and what happens on a laptop where the property is not set.