@Conditional註解使用

@Configuration
public class Config {

    @Conditional(MyCondition.class)
    @Bean
    public String condition() {
        System.err.println("自定義的condition的match方法返回值爲true時,纔會進入該方法創建bean");
        return "";
    }

    /**
     * 該Abc class位於類路徑上時
     */
    @ConditionalOnClass(Abc.class)
    @Bean
    public String abc() {
        System.err.println("ConditionalOnClass true");
        return "";
    }

//    @ConditionalOnClass(Abc.class)
//    @Bean
//    public Abc newAbc() {
//        System.err.println("ConditionalOnClass true");
//        return new Abc();
//    }

    /**
     * 存在Abc類的實例時
     */
    @ConditionalOnBean(Abc.class)
    @Bean
    public String bean() {
        System.err.println("ConditionalOnBean is exist");
        return "";
    }

    @ConditionalOnMissingBean(Abc.class)
    @Bean
    public String missBean() {
        System.err.println("ConditionalOnBean is missing");
        return "";
    }

    /**
     * 表達式爲true時
     */
    @ConditionalOnExpression(value = "true")
    @Bean
    public String expresssion() {
        System.err.println("expresssion is true");
        return "";
    }

    /**
     * 配置文件屬性是否爲true
     */
    @ConditionalOnProperty(
            value = {"abc.property"},
            matchIfMissing = false)
    @Bean
    public String property() {
        System.err.println("property is true");
        return "";
    }
}

這裏面有個空類Abc.class,你可以就創建個叫Abc的類,裏面是空的就行。

public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //判斷當前系統是Mac,Windows,Linux
        return conditionContext.getEnvironment().getProperty("os.name").contains("Mac");
    }
}

@Conditional(MyCondition.class) 這句代碼可以標註在類上面,表示該類下面的所有@Bean都會啓用配置 也可以標註在方法上面,只是對該方法啓用配置 除了自己自定義Condition之外,Spring還提供了很多Condition給我們用

@ConditionalOnBean(僅僅在當前上下文中存在某個對象時,纔會實例化一個Bean)

@ConditionalOnClass(某個class位於類路徑上,纔會實例化一個Bean)

@ConditionalOnExpression(當表達式爲true的時候,纔會實例化一個Bean)

@ConditionalOnMissingBean(僅僅在當前上下文中不存在某個對象時,纔會實例化一個Bean)

@ConditionalOnMissingClass(某個class類路徑上不存在的時候,纔會實例化一個Bean)

@ConditionalOnNotWebApplication(不是web應用)

以上是一些常用的註解,其實就是條件判斷,如果爲true了就創建Bean,爲false就不創建,就這麼簡單。

這些註解裏的條件可以是多個,也可以賦默認值,也可以標註在類上,如果標註在類上,則對類裏的所有@Bean方法都生效。

其中@ConditionalOnProperty是指在application.yml裏配置的屬性是否爲true,其他的幾個都是對class的判斷。

我在配置里加上abc.property = true這個配置就可以測試上面的代碼了。

然後再來一個對類進行多個條件標註的例子: 

@Configuration
@ConditionalOnProperty(
        value = {"abc.property"},
        matchIfMissing = false
)
@ConditionalOnClass(Abc.class)
public class Multi {
    @Bean
    @ConditionalOnMissingBean({Abc.class})
    public String check() {
        System.err.println("multi check");
        return "check";
    }
}

可能上面的那些你用的地方不常見,那我來舉一個我正在使用的例子。我的應用是基於SpringCloud的,在線上部署時有eureka來做註冊中心,而在本地環境下,我的應用是單機的,不需要eureka,但是代碼裏已經引入了eureka了,每次啓動就會自動去連接eureka,然後控制檯就開始報錯。雖然不影響功能,但是看着一直不停的報錯也是不順眼。

那麼我就可以使用Condition註解來解決它。

@Component
@ConditionalOnProperty(value = "open.eureka")
@EnableDiscoveryClient
public class JudgeEnableDiscoveryClient {
}

我把EnableDiscoveryClient這個註解單獨放個類裏,裏面什麼也不寫,條件就是application.yml裏配置的open.eureka 如果我只想讓線上的環境開啓eureka,那麼我就在application-prod.yml裏配上open.eureka=true,其他的yml什麼也不寫就行了。這樣本地啓動時就相當於沒有開啓EnableDiscoveryClient。

使用場景還是蠻多的,具體的看情況,但是需要記住有這麼個註解,以便不時之需。

轉自:https://cloud.tencent.com/developer/article/1384046

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章