Spring中@Conditional注解详解

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

前些天发现了一个巨牛的人工智能学习网站通俗易懂风趣幽默忍不住分享一下给大家。点击跳转到网站点击跳转浏览。

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

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

从代码中可以看到需要传入一个Class数组并且需要继承Condition接口

@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

Condition是个接口需要实现matches方法返回true则注入beanfalse则不注入。

用法如下

在这里插入图片描述

下面举例测试Condition的注入Bean

首先创建Dog类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dog {
    private String name;
    private String gender;
}

然后创建MyCondition类

重写matches方法 返回true则注入beanfalse则不注入
如果容器中注入了 dog 就返回true

public class MyCondition implements Condition {
    /**
     * 重写matches方法 返回true则注入beanfalse则不注入。
     * */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 如果容器中注入了 dog 就返回true
        if(beanFactory.containsBean("dog")){
            return true;
        }
        return false;
    }
}

定义两个Bean

@Configuration
public class MyConfig {

    @Bean("dog")
    //@ConditionalOnBean(name = {"dog2"})
    public Dog dog1(){
        return new Dog("金毛","公");
    }

    @Bean("dog1")
    @Conditional(value = MyCondition.class)
    public Dog dog2(){
        return new Dog("拉布拉多","母");
    }
}

测试方法AnnotationConfigApplicationContext

AnnotationConfigApplicationContext是一个独立的应用上下文它接受带注释的类作为输入。
例如@Configuration或@Component。 可以使用scan()查找 Bean也可以使用register()注册 Bean。

public class tets {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
         Map<String, Dog> beansOfType = applicationContext.getBeansOfType(Dog.class);
        System.out.println(beansOfType);
    }
}


测试结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0E3qWV9I-1673088393503)(Spring%20@Conditional%E6%B3%A8%E8%A7%A3.assets/image-20230104162057475.png)]

如果将MyCondition类中逻辑改为如果如果容器中之前注入了 dog 就返回false不注入其他的
即:

public class MyCondition implements Condition {
    /**
     * 重写matches方法 返回true则注入beanfalse则不注入。
     * */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 如果容器中之前注入了 dog 就返回false
        if(beanFactory.containsBean("dog")){
            return false;
        }
        return true;
    }
}

那么结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y5YxGAQx-1673088393504)(Spring%20@Conditional%E6%B3%A8%E8%A7%A3.assets/image-20230104162343817.png)]

@Conditional本身还是一个父注解派生出大量的子注解,如下:

@ConditionalOnBean当容器中有指定Bean的条件下进行实例化。
@ConditionalOnMissingBean当容器里没有指定Bean的条件下进行实例化。
@ConditionalOnClass当classpath类路径下有指定类的条件下进行实例化。
@ConditionalOnMissingClass当类路径下没有指定类的条件下进行实例化。
@ConditionalOnWebApplication当项目是一个Web项目时进行实例化。
@ConditionalOnNotWebApplication当项目不是一个Web项目时进行实例化。
@ConditionalOnProperty当指定的属性有指定的值时进行实例化。
@ConditionalOnExpression基于SpEL表达式的条件判断。
@ConditionalOnJava当JVM版本为指定的版本范围时触发实例化。
@ConditionalOnResource当类路径下有指定的资源时触发实例化。
@ConditionalOnJndi在JNDI存在的条件下触发实例化。
@ConditionalOnSingleCandidate当指定的Bean在容器中只有一个或者有多个但是指定了首选的Bean时触发实例化。

测试@ConditionalOnBean和@ConditionalOnMissingBean注解

修改之前的配置类如下

@Configuration
public class MyConfig {

    @Bean("dog")

    public Dog dog1(){
        return new Dog("金毛","公");
    }

    @Bean("dog1")
    @ConditionalOnBean(name = {"dog"})// spring容器中有dog这个Bean 才会创建dog1
//    @ConditionalOnMissingBean(name = {"dog"})// spring容器中不存在 dog这个Bean 才会创建dog1
    public Dog dog2(){
        return new Dog("拉布拉多","母");
    }
}

结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hPUXUWPh-1673088393505)(Spring%20@Conditional%E6%B3%A8%E8%A7%A3.assets/image-20230104163639174.png)]

然后再将第二个注释放开第一个注释注释掉
结果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z9erSSTI-1673088393505)(Spring%20@Conditional%E6%B3%A8%E8%A7%A3.assets/image-20230104163855985.png)]

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring