Spring Boot2 series of tutorials (seven) understand the principles of automated configuration

Automated configuration of Spring Boot indeed very attractive, some even say that let Java Spring Boot back to life again, although the remark sounds a bit exaggerated, but it is undeniable that, once bloated cumbersome Spring configuration does make people feel big head while Spring Boot brings new automation configuration, and indeed alleviate this problem.

If you ask how to achieve this configuration is automated, many people would say is the starter thing! Then the starter principle of what is it? Song Ge previously wrote an article about the custom starter:

This side has a very critical point, and that is the condition notes can even be said conditions annotation is the cornerstone of the entire Spring Boot.

Conditions comment is not a new thing, it's a thing in the Spring of existence, we used in the Spring profile is actually a condition annotation of specialization.

Principle Spring Boot want to find out the condition annotation must be used, so today we will come and chat Song Ge conditions comments.

definition

Spring4 provides more general conditions annotation, so that we can create different Bean in meeting different conditions, this arrangement has been widely used in the Spring Boot, a large number of automated configuration are achieved through conditions annotation, Song Ge Spring Boot View previous articles, all related to the interpretation of the source of the article, basically can not do without condition notes:

Some partners may not be used small notes conditions, but the development environment, production environment switched Profile or less have used it? In fact, this is a special case of condition annotations.

practice

Despite Spring Boot, let's simply look at the condition Spring annotation usage.

First, we create a common Maven project, then the introduction of spring-context, as follows:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
</dependencies>

Then define a Food interfaces:

public interface Food {
    String showName();
}

Food and interface has a method showName implement two classes:

public class Rice implements Food {
    public String showName() {
        return "米饭";
    }
}
public class Noodles implements Food {
    public String showName() {
        return "面条";
    }
}

Rice and Noodles are two classes, class implements two showName method then returns different values.

Then re-create the conditions were like Rice and Noodles, as follows:

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

Attribute condition matches do judgment process, when the property system people attribute value of 'north' time, NoodlesCondition conditions are met, the system when people attribute value is 'southern' time, RiceCondition conditions are met In other words, what the conditions are met, which for a while Bean will be created.

Next we configure Rice and Noodles:

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

This configuration class, we focus attention to two places:

  • Bean are two names for the food, this is not a coincidence, but intends to take. Bean return two values ​​are the parent class object Food.
  • Bean each annotation are more @Conditional, when the return value is true matches class of process conditions arranged @Conditional annotations corresponding Bean will take effect.

Once configured, we can test the main method:

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

First we create a AnnotationConfigApplicationContext instance configuration used to load Java classes, and then we add a property to the environment during and after the addition is complete, go to the configuration register our class, then refresh container. After the container refresh is complete, we can go to get food from the container instance, this example will be based on attributes of different people, created out of a different Food instances.

This is the condition Spring comment.

evolution

There is also a condition notes an evolution that Profile. To achieve rapid switching between development and production environments, we generally use Profile. In fact, Profile annotation is the use of conditions to achieve.

Or earlier example, we use a slightly modified look to Profile:

First Food, Rice Noodles and definitions do not change, we do not need the conditions of this comment, we've added @Profile comment directly when Bean is defined as follows:

@Configuration
public class JavaConfig {
    @Bean("food")
    @Profile("南方人")
    Food rice() {
        return new Rice();
    }
    @Bean("food")
    @Profile("北方人")
    Food noodles() {
        return new Noodles();
    }
}

This condition does not require a comment, replaced by @Profile. Then Main method, Bean loaded as follows:

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.getEnvironment().setActiveProfiles("南方人");
        ctx.register(JavaConfig.class);
        ctx.refresh();
        Food food = (Food) ctx.getBean("food");
        System.out.println(food.showName());
    }
}

And the effect of the above cases the same.

This looks @Profile comment seemingly even more convenient than @Conditional notes, then the notes in the end is what @Profile to achieve it?

We look @Profile definition:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
    String[] value();
}

We can see that it is implemented by the conditions comments. Condition class is ProfileCondition, we take a look:

class ProfileCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
        if (attrs != null) {
            for (Object value : attrs.get("value")) {
                if (context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value))) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }
}

See here to understand, but it is still in the condition we wrote notes in that set of things, but @Profile notes automatically help us achieve it.

@Profile is convenient, but not flexible enough, because the specific decision logic is not our own implementation. The @Conditional are more flexible.

Epilogue

Two examples to show the conditions for the use of annotations in Spring, it's a core idea is that when certain conditions are satisfied, a Bean to take effect, and it is this characteristic, support from the automation of Spring Boot configuration.

Well, we stop here, there are discussion questions please leave a message.

Public concern number [south] a little rain, focused on Spring Boot + Micro service and front and rear ends of separation full stack technology, video tutorials on a regular basis to share concerns reply after Java, Java dry Song Ge receive carefully prepared for you!

Guess you like

Origin www.cnblogs.com/lenve/p/11572518.html