@ConditionalOnProperty 用法

文章目录


前言

@ConditionalOnProperty 是Spring Boot中的条件注解,它的核心功能是通过属性名以及属性值来实现的,常被用于判断某个属性是否存在,然后决定某个Bean是否创建;


一、使用场景

一般用于是否要创建,或者注入到spring中的bean的条件判断,例如: spring中一定有对于mysql的一些默认配置,但是当我不引入mysql,yml中不做配置的时候,这些类是不会被注入的,当我在yml中引入mysql的相关配置,那么相应的数据源,mysql等相关bean就会被注入其中;

二、使用步骤

这里举个例子,也是项目中常见的问题,当一个实现类有两个实现类的时候,我们注入使用的时候会有问题;

1.错误示例

  • 一个接口
java 复制代码
public interface TestConditionOnProperty {

    void sout();
}
  • 两个实现类

    @Service
    public class TestConditionOnProperty1 implements TestConditionOnProperty {
    @Override
    public void sout() {
    System.out.println(">>>>>>>>>>>>>> TestConditionOnProperty1 <<<<<<<<<<<<");
    }
    }

    @Service
    public class TestConditionOnProperty2 implements TestConditionOnProperty {
    @Override
    public void sout() {
    System.out.println(">>>>>>>>>>>>>> TestConditionOnProperty2 <<<<<<<<<<<<");
    }
    }

  • 开始测试, 问题出现

    @SpringBootTest
    class TestConditionOnPropertyTest {

    复制代码
      @Autowired
      TestConditionOnProperty testConditionOnProperty;
    
      @Test
      void sout() {
          testConditionOnProperty.sout();
      }

    }

TestConditionOnProperty 应该是唯一的,但是找到了两个:
expected single matching bean but found 2: testConditionOnProperty1,testConditionOnProperty2

  • 解决方案: 加上@Qualifier ,指定其中一个具体实现类

    @SpringBootTest
    class TestConditionOnPropertyTest {

    复制代码
      @Qualifier("testConditionOnProperty1")
      @Autowired
      TestConditionOnProperty testConditionOnProperty;
    
      @Test
      void sout() {
          testConditionOnProperty.sout();
      }

    }

2.@ConditionalOnProperty的解决方案

  • 依然是如上代码,但是改造下,TestConditionOnProperty1 和 TestConditionOnProperty2 各增加一行代码
java 复制代码
@Service
@ConditionalOnProperty(name = "TestConditionOnProperty",havingValue = "TestConditionOnProperty1")
public class TestConditionOnProperty1 implements TestConditionOnProperty {
    @Override
    public void sout() {
        System.out.println(">>>>>>>>>>>>>> TestConditionOnProperty1 <<<<<<<<<<<<");
    }
}

@Service
@ConditionalOnProperty(name = "TestConditionOnProperty",havingValue = "TestConditionOnProperty2")
public class TestConditionOnProperty2 implements TestConditionOnProperty {
    @Override
    public void sout() {
        System.out.println(">>>>>>>>>>>>> TestConditionOnProperty2 <<<<<<<<<<<<<<");
    }
}
  • yml增加配置

    TestConditionOnProperty: TestConditionOnProperty2

@ConditionalOnProperty(name = "TestConditionOnProperty",havingValue = "TestConditionOnProperty2")其中

name 与yml配置中的 TestConditionOnProperty对应

对应后,会读取到值为TestConditionOnProperty2, 与当前注解中的havingValue 值比对

结果为true生效,注入当前bean,结果为true失效,不注入当前bean

最终其实就是只注入了一个bean

  • 再次测试

    @SpringBootTest
    class TestConditionOnPropertyTest {

    复制代码
     @Autowired
     TestConditionOnProperty testConditionOnProperty;
    
     @Test
     void sout() {
         testConditionOnProperty.sout();
     }

    }


总结

其实这个注解 @ConditionalOnProperty 相当于就是java SPI机制的另一种实现方式,更加灵活,在配置文件中更改,当注册中心为nacos,可以实现不重启项目就能自如切换相应实现类的效果;

也就是热加载的效果,热加载其实是 @RefreshScope 发生的了作用 @RefreshScope概述

相关推荐
下次再写13 小时前
互联网大厂Java面试三轮技术问答及详解——涵盖Spring Boot与微服务
java·springboot·microservices·interview
吕永强2 天前
基于SpringBoot+Vue校园报修系统的设计与实现(源码+论文+部署)
vue·毕业设计·springboot·毕业论文·报修系统·校园报修
Flittly3 天前
【SpringSecurity新手村系列】(3)自定义登录页与表单认证
java·笔记·安全·spring·springboot
Flittly4 天前
【SpringSecurity新手村系列】(2)整合 MyBatis 实现数据库认证
java·安全·spring·springboot·安全架构
极光代码工作室4 天前
基于SpringBoot的在线考试系统
java·springboot·web开发·后端开发
YDS8295 天前
大营销平台 —— 抽奖规则决策树
java·springboot·ddd
jonyleek5 天前
【JVS更新日志】物联网、动态首页插件、在线白板插件4.15更新说明!
物联网·插件·物联网平台·jvs·更新日志·动态首页·白板插件
码农张36 天前
自定义跨字段校验必填注解
springboot
格鸰爱童话6 天前
向AI学习项目技能(七)
学习·springboot
代码漫谈7 天前
微服务 vs 单体架构:架构选型、实战拆解与决策指南
java·微服务·springboot·springcloud