SpringBoot快速入门-Conditional注解详解

Conditional注解提供了一种方式可以让我们根据条件来注入对象,当条件满足时,则注入对象。
Conditional注解根据开发应用场景,定义了许多可以直接使用的Conditionalxxx。Conditional注解不仅可以用在类上,也可以用在方法上。

Conditional注解定义有以下几种:
ConditionalOnBean
ConditionalOnClass
ConditionalOnCloudPlatform
ConditionalOnExpression
ConditionalOnJava
ConditionalOnJndi
ConditionalOnMissingBean
ConditionalOnMissingClass
ConditionalOnNotWebApplication
ConditionalOnProperty
ConditionalOnResource
ConditionalOnSingleCandidate
ConditionalOnWarDeployment
ConditionalOnWebApplication

先看一个简单的demo:

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConditionTest {

    @Bean
    @ConditionalOnBean(name = "person5")
    public Person6 test1() {
        System.out.println("=================aaabbbccc1====================");
        return new Person6();
    }

    @Bean
    @ConditionalOnMissingBean(name = "person4")
    public Person6 test2() {
        System.out.println("=================aaabbbccc2====================");
        return new Person6();
    }
}

/* 输出
=================aaabbbccc1====================
=================aaabbbccc2====================
 */

demo中使用了ConditionalOnBean和ConditionalOnMissingBean注解,分别判断容器中是否存在person5,是否不存在person4,如果满足,就返回Person6。

除了使用上面提供的注解,还可以自定义Conditional的逻辑,方式就是实现Condition接口。我们还是以不同系统来注入bean来做demo演示。

public class WindowsOSServiceConditionImpl implements OSService, Condition {
    @Override
    public void doHandler() {
        System.out.println("这是Windows业务处理类");
    }

    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        String property = System.getProperty("os.name");
        if(property.equals("Windows 10")) {
            return true;
        }
        return false;
    }
}
public class LinuxOSServiceConditionImpl implements OSService, Condition {
    @Override
    public void doHandler() {
        System.out.println("这是Linux业务处理类");
    }

    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        String property = System.getProperty("os.name");
        if(property.equals("Linux")) {
            return true;
        }
        return false;
    }
}
@Configuration
public class OSServiceConditionConfiguration {

    @Bean
    @Conditional(LinuxOSServiceConditionImpl.class)
    public Person6 test1() {
        System.out.println("=================linux====================");
        return new Person6();
    }

    @Bean
    @Conditional(WindowsOSServiceConditionImpl.class)
    public Person6 test2() {
        System.out.println("=================window====================");
        return new Person6();
    }
}
/* 输出
=================window====================
 */

上面演示的都是在方法上使用@Conditional注解,如果在类上使用,相当于所有方法都适用当前的@Conditional判断逻辑,如果配置了多个条件判断类,则多个类之间的判断逻辑是且的关系。
看demo:

/**
 * 基于自定义Conditional来实现判断注入
 */
@Configuration
@Conditional({LinuxOSServiceConditionImpl.class,WindowsOSServiceConditionImpl.class})
public class OSServiceConditionConfiguration {

    @Bean
    //@Conditional(LinuxOSServiceConditionImpl.class)
    public Person6 test1() {
        System.out.println("=================linux====================");
        return new Person6();
    }

    @Bean
    //@Conditional(WindowsOSServiceConditionImpl.class)
    public Person6 test2() {
        System.out.println("=================window====================");
        return new Person6();
    }
}

demo执行后的数据为空,说明多个条件之间是“且”的判断逻辑。