Spring中@Conditional注解详解

简介: Spring中@Conditional注解详解

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


@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则注入bean,false则不注入。

用法如下


下面举例测试Condition的注入Bean


首先创建Dog类


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


然后创建MyCondition类


重写matches方法, 返回true则注入bean,false则不注入

如果容器中注入了 dog 就返回true


public class MyCondition implements Condition {
    /**
     * 重写matches方法, 返回true则注入bean,false则不注入。
     * */
    @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);
    }
}


测试结果如下



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

即:


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


那么结果如下:



@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("拉布拉多","母");
    }
}


结果如下:



然后再将第二个注释放开,第一个注释注释掉

结果如下:



结语


🔥一个人可以掌握知识,但只有与他人交流才能形成智慧。

🔥One person can acquire knowledge, but wisdom is formed only in the exchange with others.

🏆 我坚信人与人之间的差距是表面上是财富的差距,本质上是大脑中认知的差距,


我们下期再见。

相关文章
|
19天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
37 0
|
2月前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
26天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
47 4
SpringBoot必须掌握的常用注解!
|
4天前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
20 2
|
28天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
96 2
|
28天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
38 1
|
2月前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
22天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
15 0
|
2月前
|
XML Java 数据库
Spring boot的最全注解
Spring boot的最全注解
|
2月前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。