Spring中@Conditional注解的用法

 更新时间:2024年01月04日 09:49:11   作者:时间不会赖着不走  
这篇文章主要介绍了Spring中@Conditional注解的用法,@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean,需要的朋友可以参考下

@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);
    }
}

测试结果如下

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

如果将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;
    }
}

那么结果如下:

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

@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.jpg)]

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

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

到此这篇关于Spring中@Conditional注解的用法的文章就介绍到这了,更多相关@Conditional注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java协议字节操作工具类详情

    Java协议字节操作工具类详情

    这篇文章主要介绍了Java协议字节操作工具类详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 详解MyBatis XML配置解析

    详解MyBatis XML配置解析

    这篇文章主要介绍了详解MyBatis XML配置解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • SpringMVC+Mysql实例详解(附demo)

    SpringMVC+Mysql实例详解(附demo)

    本篇文章主要介绍了SpringMVC+Mysql实例详解(附demo),小编觉得挺不错的,现在分享给大家,也给大家做个参考。
    2016-12-12
  • 解决Spring Cloud Feign 请求时附带请求头的问题

    解决Spring Cloud Feign 请求时附带请求头的问题

    这篇文章主要介绍了解决Spring Cloud Feign 请求时附带请求头的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 解决@Api注解不展示controller内容的问题

    解决@Api注解不展示controller内容的问题

    这篇文章主要介绍了解决@Api注解不展示controller内容的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2022-01-01
  • 在Android的应用中实现网络图片异步加载的方法

    在Android的应用中实现网络图片异步加载的方法

    这篇文章主要介绍了在Android的应用中实现网络图片异步加载的方法,一定程度上有助于提高安卓程序的使用体验,需要的朋友可以参考下
    2015-07-07
  • java模仿实现QQ登录界面

    java模仿实现QQ登录界面

    这篇文章主要为大家详细介绍了java模仿实现qq登录界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • spring一个项目多个模块聚合打包问题解决方案(最新推荐)

    spring一个项目多个模块聚合打包问题解决方案(最新推荐)

    最近遇到个需求,针对后端解耦模块较多的项目,想在云端启动时简洁些只启动一个jar文件的情景,本文重点给大家介绍spring一个项目多个模块聚合打包问题解决方案,感兴趣的朋友一起看看吧
    2023-09-09
  • Spring RestTemplate远程调用过程

    Spring RestTemplate远程调用过程

    这篇文章主要介绍了Spring RestTemplate远程调用过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Spring实战之FileSystemResource加载资源文件示例

    Spring实战之FileSystemResource加载资源文件示例

    这篇文章主要介绍了Spring实战之FileSystemResource加载资源文件,结合实例形式分析了spring FileSystemResource加载xml资源文件的具体实现步骤与相关操作技巧,需要的朋友可以参考下
    2019-12-12

最新评论