@Conditional条件装配

spring / 341人浏览 / 0人评论
什么是Conditional条件装配?
Conditional是Spring Framework提供的一个核心注解,这个注解的作用是提供自动装配时的条件约束,一般情况下与@Configuration和Bean配合使用。

Conditional的使用

conditional的注解声明代码如下,该注解可以接收一个Condition数组。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    java.lang.Class<? extends org.springframework.context.annotation.Condition>[] value();
}
@FunctionalInterface // 正确的函数式接口
public interface Condition {
    boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata);
}

Condition是一个函数式接口,提供了matchs方法,主要提供一个条件匹配规则,返回true表示可以注入Bean,反之不注入。

基于Conditionnal自定义一个Condition

创建一个Bean

public class Test {
    private String name;
    public Test(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Test{" +
                "name='" + name + '\'' +
                '}';
    }
}

判断当前操作系统判断是Windows返回true,否则返回false

public class WindowsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //进行条件判断,如果返回true,表示需要加载该Bean,否则表示不加载
        String os = conditionContext.getEnvironment().getProperty("os.name");
        //包含Windows则说明是Windows机器,返回true
        if(os.contains("Windows")){
            return true;
        }
        return false;
    }
}

判断当前操作系统是linux返回true,否则返回false

public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //进行条件判断,如果返回true,表示需要加载该Bean,否则表示不加载
        String os = conditionContext.getEnvironment().getProperty("os.name");
        //包含linux则说明是linux机器,返回true
        if(os.contains("linux")){
            return true;
        }
        return false;
    }
}

创建一个配置类,装载Bean

@Configuration
public class ConditionConfig {
    @Bean(name = "windows")
    @Conditional({WindowsCondition.class})
    public Test test1(){
        return new Test("windows");
    }
    @Bean(name = "linux")
    @Conditional(LinuxCondition.class) //只有一个类时大括号可以去掉
    public Test test2(){
        return new Test("linux");
    }
}

运行代码测试

public static void main(String[] args) {
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ConditionConfig.class);
    String osName = annotationConfigApplicationContext.getEnvironment().getProperty("os.name");
    System.out.println("当前系统为:" + osName);
    Map<String, Test> map = annotationConfigApplicationContext.getBeansOfType(Test.class);
    System.out.println(map.toString());
}

返回:

输入图片说明
只输出了一个Windows,因为我本机电脑是Windows系统。
接着我们测试在linux环境下的输出,通过修改运行时参数达到在linux下测试

输入图片说明
继续运行刚才的测试代码,返回:

输入图片说明
通过以上演示案例,我们实现了简单的通过判断当前系统加载Bean。

Conditionnal扩展使用方式

  • ConditionalOnBean/ConditionalOnMissingBean:容器中存在某个类或者不存在某个Bean时进行Bean装载
  • ConditionalOnClass/ConditionalOnMissingClass:classpath下存在指定类或者不存在指定类时进行Bean装载
  • ConditionalOnCloudPlatform:只有运行在指定的云平台上才加载指定的Bean
  • ConditionalOnExpression:基于SpE1表达式的条件判断
  • ConditionalOnJava:只有运行指定版本的Java才会加载Bean
  • ConditionalOnJndi:只有指定的资源通过JNDI加载后才加载Bean
  • ConditionalOnWebApplication/ConditionalOnNotWebApplication:如果是Web应用或者不是Web应用才加载指定的Bean
  • ConditionalOnProperty:系统中指定的对应的属性是否有对应的值
  • ConditionalOnResource:要加载的Bean依赖指定资源是否存在于classpath中
  • ConditionalOnSingleCandidate:只有在确定了给定Bean类的单个候选项时才会加载Bean


0 条评论

还没有人发表评论

发表评论 取消回复

记住我的信息,方便下次评论
有人回复时邮件通知我