Spring Boot of Conditional Extended

I. Introduction

This article Laijiangjiang Conditional major role, and implementation of a principle, only a thorough understanding of the Conditional series, in order to better learning automatic configuration spring boot, because it is a great tool for automatic configuration can be achieved! Focuses on the following aspects Conditional

  • Conditional is and what role
  • Conditional principle
  • Conditional series
  • Application of Conditional series in the Spring Boot


What is the role and two .Conditional

Conditional is a comment spring framework spring-context module provides, is to create conditions for spring container Bean, if conditions are met, the Bean is created, or not created.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Conditional {
    Class<? extends Condition>[] value();
}

When the value Condition condition annotation of all the matches, create Bean, or not created.

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

Condition specific conditions, is the use of Conditional Condition, on the contrary, is a mode of action Condition of Conditional.

If the match, matches returns true. ConditionContext context parameter is a conditional match logic, it can be used to access the container, the registrar, and the environment. AnnotatedTypeMetadata is Conditional notes the role of the type of metadata. Use both, you can customize to match their own terms.

Instance can be seen, such as ProfileCondition,

class ProfileCondition implements Condition {

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

Returns true if the profile and the profile of the annotation matching the specified environment, can be configured so Bean different depending on the environment, or some designated Bean only take effect in a particular environment.


Three principles .Conditional

Conditional annotation processor is ConditionEvaluator, will resolve its internal Conditional annotation, get all the notes Condition value to configure and execute match the method Condition:

public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) {
    // 如果未被Conditional注释,则返回
    if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
        return false;
    }
    if (phase == null) {
        // 如果是注解metadata,且是配置类,则执行配置阶段的Condition
        if (metadata instanceof AnnotationMetadata &&
                ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
            return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
        }
        // 否则解析注册Bean阶段的Condition
        return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
    }
    // 获取Conditional注解的value,所有的Condition
    List<Condition> conditions = new ArrayList<Condition>();
    for (String[] conditionClasses : getConditionClasses(metadata)) {
        for (String conditionClass : conditionClasses) {
            Condition condition = getCondition(conditionClass, this.context.getClassLoader());
            conditions.add(condition);
        }
    }
    // 执行所有的Condition,只要其中一个不满足,则返回true,表示应该跳过
    AnnotationAwareOrderComparator.sort(conditions);
    for (Condition condition : conditions) {
        ConfigurationPhase requiredPhase = null;
        if (condition instanceof ConfigurationCondition) {
            requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
        }
        if (requiredPhase == null || requiredPhase == phase) {
            if (!condition.matches(this.context, metadata)) {
                return true;
            }
        }
    }
    return false;
}

ConditionEvaluator responsible for Conditional notes, however ConditionEvaluator call is in the major BeanDefinitionReader or Configuration Class parser:

  • ConfigurationClassParser, which is responsible for parsing Configuration Class definitions are annotated in the beginning of parsing, calls ConditionEvaluator, execution Condition match. If not match, the configuration will be skipped class, is not processed
  • ConfigurationClassBeanDefinitionReader, which is responsible for reading and parsing ConfigurationClassParser be generated after the full Configuration Class (such as import, bean methods) treatment, processing Bean method will be invoked when the import ConditionEvaluator, if not match, the method returns Bean does not perform or not processing import
  • AnnotatedBeanDefinitionReader, which handles Bean definitions (such as Configuration / Component) annotated at the beginning of treatment, if annotated Conditional Bean is modified, is to call ConditionEvaluator processed, if not match, then this is not the definition of Bean annotated processing

Conditional annotation process is a comprehensive ConditionEvaluator and above BeanDefinition Reader and Parser, and play a role in the implementation of Condition at the configuration of parsing.


Four. Conditional form

The aforementioned Conditional annotation spring-context is defined in the module, but with the use of Conditional Condition and need to apply in a variety of scenarios, so that application developers need to write the corresponding Condition, can not be done out of the box, Comparison up trouble.

Therefore, spring boot of Conditional done a lot of expansion to accommodate various application scenarios. This creates a Conditional series, listed here only some common

  • ConditionalOnBean, only match a particular bean when beanfactory. Commonly used in between bean associated with dependence registration
  • ConditionalOnClass, bean match only a particular class path. When used in a given block is referenced, the bean register, such as spring boot autoconfiguration
  • ConditionalOnMissingBean, not only when a particular bean beanfactory match. Commonly used to prevent duplicate registration
  • ConditionalOnMissingClass, bean not only match a particular road category. Commonly used in automatic configuration, a bean does not exist, before registering another bean
  • ConditionalOnWebApplication, only match when web applicationContext. If it is commonly used in the web environment, some bean registration and web environments associated
  • ConditionalOnResource, matched only in the presence of certain resources
  • ConditionalOnProperty, only match a particular attribute is present environment, the need exists and by default is true. Used to switch register certain bean, or policy mode
  • When ConditionalOnNotWebApplication, only non-matching web applicationContext


FIVE .Conditional series in the Spring Boot

1.spring boot in DispatcherServlet registered to the Web container




In above figure, when DispatcherServlet In this context, the registration ServletRegistrationBean. The Bean for DispatcherServlet registered into the web container. ConditionalOnBean used to rely registered between Bean.

Autoconfiguration 2.spring boot data source




When DataSource and on the classpath EmbeddedDatabaseType simultaneously, automatically configure Datasource. So only need to introduce the spring-boot-starter-jdbc, can be completed automatically configure the data source. Because Datasource is jdk classes, bound on the classpath. spring-boot-starter-jdbc passed in the spring-jdbc dependent module, thereby introducing EmbeddedDatabaseType classpath, to complete the datasource auto configuration.


VI. Summary

Conditional spring is conditional upon registration for bean choice to decide whether to register the Bean. Automatic Configuration really shine on the occasion of still spring boot of large number of applications. Conditional is automatically configured, multi-environment, configure dynamic weapon.

Guess you like

Origin www.cnblogs.com/lxyit/p/12511735.html