Spring-Boot autoconfigure之Condition

本文主要介紹spring和springboot提供的幾個(gè)annotation和interface實(shí)現(xiàn)符合幾種既定條件或自定義條件下的autoconfigure


一、spring實(shí)現(xiàn)自定義條件下的autoconfigure

spring為我們提供了@ConditionalCondition.class搭配使用的方式實(shí)現(xiàn)自定義條件下的autoconfigure,源碼如下:

Condition.png

@Conditional.png

編寫一個(gè)class,繼承Condition這個(gè)接口,重寫matches()方法,當(dāng)該方法返回true時(shí)auto-configure生效,反之不生效,代碼如下

public class MyCondition implements Condition {

    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

        //what.is.you.name的value寫在application.properties中
        String name = conditionContext.getEnvironment().getProperty("what.is.you.name");
        return "bamu".equals(name);
    }
}

matches方法提供了ConditionContextAnnotatedTypeMetadata兩個(gè)參數(shù),我們可以通過ConditionContext獲取到編寫在application-xxx.properties中的配置信息。

application.properties配置文件內(nèi)容如下:注意我們現(xiàn)在定義的value和Mycondition中定義的不同

what.is.you.name=heiheihei

編寫一個(gè)Config類,其中runnableBean1、runnableBean3需要滿足我們以上自定義的條件才允許被自動(dòng)注入。

@SpringBootConfiguration
public class ConditionBeanConfig {

    @Bean
    @Conditional(MyCondition.class)
    public Runnable runnableBean1() {
        return () ->{};
    }

    @Bean
    public Runnable runnableBean2() {
        return () ->{};
    }

    @Bean
    @Conditional(MyCondition.class)
    public Runnable runnableBean3() {
        return () ->{};
    }
}

執(zhí)行main方法結(jié)果如下:

@SpringBootApplication
public class BlogApplication {

    public static void main(String[] args) {

        ConfigurableApplicationContext context = SpringApplication.run(BlogApplication.class, args);
        String[] beans = context.getBeanNamesForType(Runnable.class);
        System.out.println(Arrays.toString(beans));

        context.close();
    }
}

heiheihei.png

修改application.properties,將value改為MyCondition.class中定義的值后執(zhí)行結(jié)果如下:

bamu.png

我們發(fā)現(xiàn),自定義的MyCondition已經(jīng)生效。細(xì)心的讀者可能發(fā)現(xiàn),@Conditional注解源碼中傳入的value是一個(gè)數(shù)組Class<? extends Condition>[] value();,所以我們可以傳入多個(gè)自定義Condition,例如@Condition({MyCondition.class, YourCondition.class})

另外,@Conditianal不僅可以寫在方法上,還可以寫在configuration.class上,這樣該類中的所有bean都需要滿足自定義的Condition才能被自動(dòng)加載。

二、spring-boot提供的幾個(gè)autoconfigure annotation

springboot為我們提供了一批實(shí)用的XxxCondition,查看了他們的源碼后發(fā)現(xiàn),他們都實(shí)現(xiàn)了spring提供的Condition接口,然后編寫對(duì)應(yīng)的annotation。我們?cè)谑褂盟麄兊臅r(shí)候,只需要在需要的地方寫上這些annotation就好了。這些注解都在springboot提供的jar包中
package org.springframework.boot.autoconfigure.condition

springboot提供的Condition注解.png

通過這幾個(gè)annotation的命名,我們已經(jīng)能夠大概的猜測(cè)到他們能夠?qū)崿F(xiàn)哪些功能。以下舉出其中幾個(gè)比較常用的注解用法,讀者可以查看源碼,知曉具體的使用方式。

1)@ConditionalOnBean/@ConditionalOnMissingBean當(dāng)容器中存在/不存在某個(gè)bean時(shí),加上此注解的bean被自動(dòng)注入

@ConditionalOnBean
    @Bean
    @ConditionalOnBean(name="com.springboot.condition.User")
    public Runnable runnableBean2() {
        return () ->{};
    }

    @Bean
    @ConditionalOnBean(value=User.class)
    public Runnable runnableBean2() {
        return () ->{};
    }

2)@ConditionalOnJava根據(jù)當(dāng)前使用的JDK版本,判斷是否自動(dòng)注入

    //使用jdk8才注入此bean
    @Bean
    @ConditionalOnJava(ConditionalOnJava.JavaVersion.EIGHT)
    public Runnable runnableBean2() {
        return () ->{};
    }

3)@ConditionalOnWebApplication/@ConditionalOnWebApplicationweb環(huán)境下加載/不加載此bean

    @Bean
    @ConditionalOnWebApplication
    public Runnable runnableBean2() {
        return () ->{};
    }

好了,Spring-Boot autoconfigure之Condition就到這里,有興趣的讀者可以自己去試驗(yàn)一下。接下來會(huì)持續(xù)推出一系列Java干貨,敬請(qǐng)期待。如果有不正確或是不完整的地方,還望讀者不吝賜教,直接評(píng)論!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容