Spring 注解开发之 @Conditional

时间:2022-07-22
本文章向大家介绍Spring 注解开发之 @Conditional,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

这次介绍一下 Spring 中的一个重要的注解 @Conditional

本文的组织结构如下:

  • 先看一下该注解的作用是什么;
  • 再总览这些注解有哪些属性值;
  • 最后讲解一下重要的属性值。

Spring 版本 5.1.2.RELEASE

一、注解的作用

SpringBoot 中经常看到该注解及其衍生注解,它的作用是根据条件注入组件。

这里我们先创建出两个 Bean 作为例子:

@Bean("bill")
@Conditional({WindowsCondition.class})
public Person person2() {
    return new Person("比尔盖茨", 60);
}
@Bean("linus")
@Conditional({LinuxCondition.class})
public Person person3() {
    return new Person("李纳斯", 50);
}

这段代码的意思是:如果当前操作系统是 Windows 就将 比尔盖茨 放入容器中,如果是 Linux 就将 李纳斯 放入容器中。

ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] names = context.getBeanNamesForType(Person.class);
for (String name : names) {
    System.out.println(name);
}
// 获取当前的环境: Windows 10
String os = context.getEnvironment().getProperty("os.name");
System.out.println(os);

经过测试得到这里的环境是 Windows 10 。

二、属性总览

该注解只有一个属性。

Class<? extends Condition>[] value();

需要一个 Condition 的子类,所以我们需要自己实现一个子类。

这里我创建了两个子类分别是:

  • WindowsCondition:判断是不是 Windows 操作系统;
  • LinuxCondition:判断是不是 Linux 操作系统;

三、重要属性讲解

来看一下具体的实现类,以 WindowsCondition 为例:

public class WindowsCondition implements Condition {

    /**
     * 判断是否符合
     *
     * @param context  判断条件可以使用的上下文环境
     * @param metadata 注释信息
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 获取 IOC 使用的 beanFactory
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

        // 获取到 Bean 的注册类
        BeanDefinitionRegistry registry = context.getRegistry();
        boolean cont = registry.containsBeanDefinition("person");

        // 获取当前的环境信息
        Environment environment = context.getEnvironment();

        String property = environment.getProperty("os.name");

        // 如果是 win 系统就返回 true
        return property != null && property.contains("Windows");
    }
}

需要实现一个 match 方法。

这里通过操作系统判断了是不是满足条件,还可以通过 Bean 的注册类设置更多的条件,比如这里的 registry.containsBeanDefinition("person"); 判断是否容器中存在 person 这个 Bean

LinuxCondition 的实现如下:

public class LinuxCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String name = context.getEnvironment().getProperty("os.name");
        return name != null && name.contains("linux");
    }
}

这样经过测试容器中就只有比尔盖茨: