Spring-Boot autoconfigure之Condition

本文主要介绍spring和springboot提供的几个annotation和interface实现符合几种既定条件或自定义条件下的autoconfigure


一、spring实现自定义条件下的autoconfigure

spring为我们提供了@ConditionalCondition.class搭配使用的方式实现自定义条件下的autoconfigure,源码如下:

Spring-Boot autoconfigure之Condition_第1张图片
Condition.png

Spring-Boot autoconfigure之Condition_第2张图片
@Conditional.png

编写一个class,继承Condition这个接口,重写matches()方法,当该方法返回true时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两个参数,我们可以通过ConditionContext获取到编写在application-xxx.properties中的配置信息。

application.properties配置文件内容如下:注意我们现在定义的value和Mycondition中定义的不同

what.is.you.name=heiheihei

编写一个Config类,其中runnableBean1、runnableBean3需要满足我们以上自定义的条件才允许被自动注入。

@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 () ->{};
    }
}

执行main方法结果如下:

@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();
    }
}

Spring-Boot autoconfigure之Condition_第3张图片
heiheihei.png

修改application.properties,将value改为MyCondition.class中定义的值后执行结果如下:

Spring-Boot autoconfigure之Condition_第4张图片
bamu.png

我们发现,自定义的MyCondition已经生效。细心的读者可能发现,@Conditional注解源码中传入的value是一个数组Class[] value();,所以我们可以传入多个自定义Condition,例如@Condition({MyCondition.class, YourCondition.class})

另外,@Conditianal不仅可以写在方法上,还可以写在configuration.class上,这样该类中的所有bean都需要满足自定义的Condition才能被自动加载。

二、spring-boot提供的几个autoconfigure annotation

springboot为我们提供了一批实用的XxxCondition,查看了他们的源码后发现,他们都实现了spring提供的Condition接口,然后编写对应的annotation。我们在使用他们的时候,只需要在需要的地方写上这些annotation就好了。这些注解都在springboot提供的jar包中
package org.springframework.boot.autoconfigure.condition

Spring-Boot autoconfigure之Condition_第5张图片
springboot提供的Condition注解.png

通过这几个annotation的命名,我们已经能够大概的猜测到他们能够实现哪些功能。以下举出其中几个比较常用的注解用法,读者可以查看源码,知晓具体的使用方式。

1)@ConditionalOnBean/@ConditionalOnMissingBean当容器中存在/不存在某个bean时,加上此注解的bean被自动注入

Spring-Boot autoconfigure之Condition_第6张图片
@ConditionalOnBean
    @Bean
    @ConditionalOnBean(name="com.springboot.condition.User")
    public Runnable runnableBean2() {
        return () ->{};
    }

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

2)@ConditionalOnJava根据当前使用的JDK版本,判断是否自动注入

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

3)@ConditionalOnWebApplication/@ConditionalOnWebApplicationweb环境下加载/不加载此bean

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

好了,Spring-Boot autoconfigure之Condition就到这里,有兴趣的读者可以自己去试验一下。接下来会持续推出一系列Java干货,敬请期待。如果有不正确或是不完整的地方,还望读者不吝赐教,直接评论!

你可能感兴趣的:(Spring-Boot autoconfigure之Condition)