Details of @ ConditionalOnProperty in Spring Boot

Keywords: Java Spring encoding Tomcat Attribute

We often see the use of @ ConditionalOnProperty annotation in the automatic configuration of Spring Boot. This article will take you to understand the function of this annotation.

Use in Spring Boot

In the source code of Spring Boot, for example, automatic configuration involving Http encoding, automatic configuration of data source type, etc., a lot of @ ConditionalOnProperty annotations are used.

Part of the source code in HttpEncodingAutoConfiguration class:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
    // Omit internal code
}

Some codes in DataSourceConfiguration class:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource",
        matchIfMissing = true)
static class Tomcat {
  // Omit internal code
}

Obviously, in the above two auto configuration classes, @ ConditionalOnProperty is used to control whether the auto configuration takes effect. Let's take a look at its source code and specific use.

@ConditionalOnProperty source code description

@The source code of ConditionalOnProperty annotation class is as follows:

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {

    // Array, get the value of the corresponding property name, which cannot be used at the same time as name
    String[] value() default {};

    // Configure the prefix of the property name, such as spring.http.encoding
    String prefix() default "";

    // Array, configuration property full or partial name
    // It can be combined with prefix to form a complete configuration attribute name. It cannot be used with value at the same time
    String[] name() default {};

    // It can be used in combination with name to compare whether the obtained property value is the same as the value given by havingValue, and load the configuration only when it is the same
    String havingValue() default "";

    // Whether the configuration property can be loaded when it is missing. If it is true, it will load normally without the configuration attribute; otherwise, it will not take effect
    boolean matchIfMissing() default false;

}

There is also a relaxedNames attribute in the historical version:

//Whether it can be loosely matched
boolean relaxedNames() default true;

The property no longer exists in the latest version.

By annotating @ Conditional(OnPropertyCondition.class) code on ConditionalOnProperty, we can see that ConditionalOnProperty belongs to the derived annotation of @ Conditional. The validation condition is determined by OnPropertyCondition.

Usage method

We have seen the usage of @ ConditionalOnProperty in the Spring Boot above.

@The core function of ConditionalOnProperty is realized by the property name and havingValue.

First, look at the matchIfMissing property, which is used to specify the default processing when the corresponding property is not configured in the configuration file: by default, matchIfMissing is false, that is to say, if the property is not configured, the automatic configuration does not take effect. If matchIfMissing is true, it means that if there is no corresponding property configuration, the automatic configuration takes effect by default.

Next, look at the name property, which is used to read a property value from application.properties. For example, the configuration file of Tomcat is as follows:

spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource

When matchIfMissing is false, if the name value is empty, then false will be returned; if the name is not empty, then the value will be compared with the value specified by havengvalue, if the same, then true will be returned, otherwise false will be returned. Returning false also means that automatic configuration will not take effect.

However, if you look at the property configuration on the HttpEncodingAutoConfiguration class, you can see that it is not fully used in accordance with the above-mentioned name and havingValue. It is configured with "prefix+value" as the name of the attribute:

spring.http.encoding.enabled=true

Where prefix specifies the unified prefix of configuration "spring.http.encoding", and value specifies the specific attribute name "enabled". The value of havingValue is not set here. If the value of havingValue is not specified, the value set in the property configuration by default is true, which takes effect (as configured above). false does not take effect.

Original link:< Detailed use of @ continionalproperty in SPRING BOOT>


New vision of < center > program: you can't miss the highlights and growth < / center >

Posted by nocontrol on Mon, 09 Dec 2019 04:33:25 -0800