Condition annotation of automatic configuration in SpringBoot @ condition

The once bloated and cumbersome Spring configuration really makes people feel big, and the new automatic configuration brought by Spring Boot really alleviates this problem.

In automatic configuration, there is a very key point, that is, conditional annotation. It can even be said that conditional annotation is the cornerstone of the whole Spring Boot.

Conditional annotation is not a new thing. It is a thing existing in Spring. The profile we often use in Spring is actually a specialization of conditional annotation.

Spring 4 provides more general conditional annotation, which allows us to create different beans when meeting different conditions. This configuration method is widely used in Spring Boot, and a large number of automatic configurations are realized through conditional annotation.

practice

Conditional annotation in Spring

Define the interface first

public interface Food {
    String showName();
}

Define two implementation classes

public class Rice implements Food {
    public String showName() {
        return "Steamed Rice";
    }
}
public class Noodles implements Food {
    public String showName() {
        return "noodle";
    }
}

Define condition class

public class RiceCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().getProperty("people").equals("Southerner");
    }
}
public class NoodlesCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().getProperty("people").equals("Northerners");
    }
}

Define java configuration class

@Configuration
public class JavaConfig {
    @Bean("food")
    @Conditional(RiceCondition.class)
    Food rice() {
        return new Rice();
    }

    @Bean("food")
    @Conditional(NoodlesCondition.class)
    Food noodles() {
        return new Noodles();
    }
}

For this configuration class, you should pay attention to two points:

  • It's not a coincidence that the names of both beans are food. It's intentional. The return value of both beans is their parent object, food.

  • There are @ Conditional annotations on each Bean. When the return value of the matches method of the condition class configured in the @ Conditional annotation is true, the corresponding Bean will take effect.

After configuration, we can test in the main method:

public class TestCondition {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.getEnvironment().getSystemProperties().put("people", "Southerner");
        ctx.register(JavaConfig.class);
        ctx.refresh();
        Food food = (Food) ctx.getBean("food");
        System.out.println(food.showName());
    }
}

Note: Junit testing is not available because configuration values need to be written to the environment.

Upgrade @ Profile of conditional annotation in SpringBoot

First of all, the definitions of Food, Rice and foodles do not need to change

Add @ Profile annotation directly to Bean definition

@Configuration
public class JavaConfig2 {
    @Bean("food")
    @Profile("Southerner")
    Food rice() {
        return new Rice();
    }
    @Bean("food")
    @Profile("Northerners")
    Food noodles() {
        return new Noodles();
    }
}

Test:

public class TestCondition2 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.getEnvironment().setActiveProfiles("Southerner");
        ctx.register(JavaConfig2.class);
        ctx.refresh();
        Food food = (Food) ctx.getBean("food");
        System.out.println(food.showName());
    }
}

summary

@The Profile annotation automatically helps us implement the set of things we write in the conditional annotation.

@Although the Profile is convenient, it is not flexible enough, because the specific judgment logic is not implemented by ourselves. And @ Conditional is more flexible.

Two examples show you the use of conditional annotation in Spring. One of its core ideas is that when certain conditions are met, a Bean will take effect. This feature supports the automatic configuration of Spring Boot.

Published 13 original articles, praised 0, visited 1691
Private letter follow

Tags: Spring Java Junit SpringBoot

Posted on Tue, 04 Feb 2020 22:50:26 -0500 by davidjwest