Spring 注解之 Conditional 使用

117 阅读2分钟

Spring 注解之 Conditional 使用

前言

在Spring 中我们要是注册bean使用 @Bean @Component等注解执行在会像容器中注册Bean,但有的时候我们需要根据条件进行注册Bean,哪些需要注册到Ioc中,哪些不需要。

@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。

注解详情

org.springframework.context.annotation;包下

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}

可以看到该注解可以指定在方法上也作用在类中。

可以看到传入参数可以传入多个类

代码示例

根据操作系统来指定像Ioc容器中注入那种Bean

分别创建 Persion1 和 Persion2 两个类

public class Persion1 {
    private String namel;

    public Persion1(String namel) {
        this.namel = namel;
    }

    public String getNamel() {
        return namel;
    }

    public void setNamel(String namel) {
        this.namel = namel;
    }
}
public class Persion2 {
    private String namel;
    public Persion2(String namel) {
        this.namel = namel;
    }
    public String getNamel() {
        return namel;
    }

    public void setNamel(String namel) {
        this.namel = namel;
    }
}

实现 Condition 接口 根据环境判断操作系统是Windows 还是 Linux

Condition 接口详情

public interface Condition {
    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}

参数 ConditionContext var1

参数 AnnotatedTypeMetadata var2

ConditionContext 接口

public interface ConditionContext {
    BeanDefinitionRegistry getRegistry();

    ConfigurableListableBeanFactory getBeanFactory();

    Environment getEnvironment();

    ResourceLoader getResourceLoader();

    ClassLoader getClassLoader();
}

接口方法说明

    //1 获取环境
    Environment environment = conditionContext.getEnvironment();
    //2 获取类加载器
    //ClassLoader classLoader = conditionContext.getClassLoader();
    //3 获取ioc使用beanFactory
    //ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
    //4 获取bean定义的注册类 可以对bean进行操作
    //BeanDefinitionRegistry registry = conditionContext.getRegistry();

编写对操作系统条件判断方法

public class ConditionalTest1 implements Condition {

    //conditionContext 能使用的上下文环境
    //annotatedTypeMetadata 注释信息
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //1 获取环境
        Environment environment = conditionContext.getEnvironment();
        //2 获取类加载器
        //ClassLoader classLoader = conditionContext.getClassLoader();
        //3 获取ioc使用beanFactory
        //ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
        //4 获取bean定义的注册类 可以对bean进行操作
        //BeanDefinitionRegistry registry = conditionContext.getRegistry();


        String property = environment.getProperty("os.name");
        if (property.contains("Windows")) {
            return true;
        }

        return false;
    }
}

同理对Linux

public class ConditionalTest2 implements Condition {

    //conditionContext 能使用的上下文环境
    //annotatedTypeMetadata 注释信息
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        if (property.contains("Linux")) {
            return true;
        }

        return false;
    }
}

根据不同的操作系统注入不同的类

ConditionalTest1 注入windows
ConditionalTest2 注入linux

@Configuration
public class Concfigration {

    @Bean
    @Conditional(ConditionalTest1.class)
    public Persion1 persion1(){
        return new Persion1("windows");
    }

    @Bean
    @Conditional(ConditionalTest2.class)
    public Persion2 persion2(){
        return new Persion2("linux");
    }
}

测试

    @Test
    public void testEnviriment(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Concfigration.class);
        //获取ioc当前系统环境
        Environment environment = applicationContext.getEnvironment();

        String property = environment.getProperty("os.name");
        System.out.println(property);
        if (property.contains("Windows")) {
            Persion1 persion1 = applicationContext.getBean( Persion1.class);
            System.out.println("persion1 = " + persion1);
        }

        if (property.contains("Linux")) {
            System.out.println("linux");
            Persion2 persion2 = applicationContext.getBean(Persion2.class);
            System.out.println("persion1 = " + persion2);
        }



    }
}

Windows 下测试结果

Windows 7
persion1 = com.example.springdemo.conditional.Persion1@6b2e46af

Linux 下测试

可以在Linux下测试代码

也可以设置JVM参数 设置操作系统

在这里插入图片描述

linux
persion1 = com.example.springdemo.conditional.Persion2@88a8218

Conditional 注解在Spring Boot中大量使用

比如 Spring Boot中选择容器,根据条件查看类路径下是否有指定的包

在这里插入图片描述

可以看到注解

在这里插入图片描述
具体OnClassCondition 去判断类路径下是有相应的容器依赖。