1. 程式人生 > >spring boot自動配置的實現原理——@Conditional

spring boot自動配置的實現原理——@Conditional

spring 4中引入了@Conditional註解,可以讓spring在滿足特定條件時才將一個類註冊到spring容器中,具體的條件由org.springframework.context.annotation.Condition介面來描述,該介面的定義如下

@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}

讓我們先寫一個自定義的Condition來試一下。假設我希望如果當前classpath中如果包含了mysql-connector的類的話,條件就成立,我可以定義這麼一個類

public class MysqlCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        try{
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            return
false; } return true; } }

這就是一個自定義的Condition。接下來,如果我希望如果當前classpath中如果包含了mysql-connector的類的話,我就向spring中注入一個String字串


import com.example.springbootstart.conditions.MysqlCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation
.Conditional; import org.springframework.context.annotation.Configuration; @Configuration public class ConditionalConfig { @Conditional(MysqlCondition.class) @Bean public String hello(){ return "hello, i am here"; } }

以上是spring基於java的配置。如果MysqlCondition條件成立,則注入一個String型別的bean,name=hello

這就是spring@Conditional的簡單用法,由於所謂的Condition是通過一個介面來描述的,所以開發人員可以定義各種各樣的condition。spring還內建了一些比較常用的Condition

Conditions 描述
@ConditionalOnBean / @ConditionalOnMissingBean 是否存在某個型別或name的bean
@ConditionalOnClass / @ConditionalOnMissingClass 當前classpath是否存在某個型別
@ConditionalOnResource 當前classpath是否存在某個資原始檔
@ConditionalOnProperty 當前jvm是否包含某個系統屬性為某個值
@ConditionalOnWebApplication 當前spring context是否是web應用程式

如果不自定義上面的@ConditionalOnClass,可以直接使用@ConditionalOnClass(name = {"com.mysql.jdbc.Driver"})來達到同樣的目的

@Configuration
public class ConditionalConfig {

    //    @Conditional(MysqlCondition.class)
    @ConditionalOnClass(name = {"com.mysql.jdbc.Driver"})
    @Bean
    public String hello() {
        return "hello, i am here";
    }
}