Spring Boot条件注解之@ConditionalOnProperty完全解析

 更新时间:2025年02月13日 10:53:03   作者:CodeDunkster  
这篇文章主要介绍了SpringBoot中的@ConditionalOnProperty注解,通过配置文件属性值控制Bean或配置类的加载,实现功能开关和环境配置,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在 Spring Boot 项目中,有时候我们希望根据配置文件中的某个属性值来决定是否启用某个功能或加载某个组件。此时,@ConditionalOnProperty 注解就可以发挥作用。它通过配置文件的属性值控制 Bean 或配置类的加载,使得我们的程序更具灵活性。

本文将详细介绍 @ConditionalOnProperty 的用法,并通过 功能开关 和 环境配置 两个实际场景来展示它的强大之处。

1. @ConditionalOnProperty 基本用法

语法

@ConditionalOnProperty(
    prefix = "前缀",
    name = "属性名",
    havingValue = "指定值",
    matchIfMissing = false
)

参数说明:

  • prefix:属性的前缀部分。
  • name:属性名称。
  • havingValue:属性的值与 havingValue 相等时条件成立(默认不指定)。
  • matchIfMissing:如果属性未定义,是否加载配置(默认 false,即未定义时不加载)。

2. 实战场景

场景一:功能开关

在实际项目中,我们可能需要通过配置文件中的某个属性来控制某个功能的启用或禁用。比如,是否开启定时任务、是否启用某个服务等。

示例:通过功能开关启用日志增强功能

Step 1:配置文件定义开关

在 application.properties 文件中添加一个开关属性:

feature.logging-enhancement.enabled=true

Step 2:实现日志增强功能

使用 @ConditionalOnProperty 来决定是否加载日志增强的 Bean:

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnProperty(prefix = "feature.logging-enhancement", name = "enabled", havingValue = "true", matchIfMissing = false)
public class LoggingEnhancementConfig {

    @Bean
    public String loggingEnhancement() {
        System.out.println("日志增强功能已启用!");
        return "Logging Enhancement Activated";
    }
}

Step 3:测试

  • 当 feature.logging-enhancement.enabled=true 时,LoggingEnhancementConfig 类会被加载,控制台会输出:
    日志增强功能已启用!
    
  • 当 feature.logging-enhancement.enabled=false 或未配置时,LoggingEnhancementConfig 类不会被加载。

场景二:环境配置

在不同的环境(开发、测试、生产)中,我们可能需要加载不同的配置。例如,开发环境下使用内存数据库,生产环境下使用 MySQL 数据库。

示例:不同环境下选择数据源

Step 1:配置文件

在 application.properties 中配置环境标识:

# 开发环境
spring.datasource.env=dev

# 生产环境
# spring.datasource.env=prod

Step 2:开发环境数据源配置

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

@Configuration
@ConditionalOnProperty(prefix = "spring.datasource", name = "env", havingValue = "dev")
public class DevDataSourceConfig {

    @Bean
    public DataSource devDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:testdb");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        System.out.println("开发环境:加载内存数据库");
        return dataSource;
    }
}

Step 3:生产环境数据源配置

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

@Configuration
@ConditionalOnProperty(prefix = "spring.datasource", name = "env", havingValue = "prod")
public class ProdDataSourceConfig {

    @Bean
    public DataSource prodDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/proddb");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        System.out.println("生产环境:加载 MySQL 数据库");
        return dataSource;
    }
}

Step 4:测试

  • 开发环境spring.datasource.env=dev控制台输出:

    开发环境:加载内存数据库
    
  • 生产环境spring.datasource.env=prod控制台输出:

    生产环境:加载 MySQL 数据库
    

3. 常见应用场景总结

  • 功能开关:动态启用或禁用某个功能模块(如定时任务、监控服务等)。
  • 环境配置:根据不同环境加载不同的配置(如数据源、日志级别等)。
  • 组件选择:根据配置加载特定的第三方组件(如不同的缓存实现 Redis/ehcache)。
  • 服务切换:实现备用服务或降级服务的自动切换。

4. 小结

@ConditionalOnProperty 是 Spring Boot 中非常实用的条件注解,可以通过配置文件灵活地控制 Bean 和配置类的加载,避免不必要的资源浪费,并提高系统的可维护性。

通过功能开关和环境配置的示例,我们可以看到 @ConditionalOnProperty 如何让代码更清晰、配置更灵活,极大地满足了开发者在不同场景下的需求。

最佳实践

  • 配置文件中使用统一的前缀管理属性,避免冲突。
  • 开关属性的命名要清晰直观,比如 feature.xxx.enabled
  • 对于重要的功能开关,可以结合文档明确其作用和默认值。

希望这篇博客能帮助你更好地掌握 @ConditionalOnProperty 的用法,让你的 Spring Boot 项目更加灵活和可配置!

总结

到此这篇关于Spring Boot条件注解之@ConditionalOnProperty完全解析的文章就介绍到这了,更多相关SpringBoot条件注解@ConditionalOnProperty内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring+springmvc+mybatis+maven入门实战(超详细教程)

    spring+springmvc+mybatis+maven入门实战(超详细教程)

    这篇文章主要介绍了spring+springmvc+mybatis+maven入门实战(超详细教程),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • java方法重载和参数类型自动提升方式

    java方法重载和参数类型自动提升方式

    这篇文章主要介绍了java方法重载和参数类型自动提升方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 解决IDEA2020.2插件lombok报错问题(亲测有效)

    解决IDEA2020.2插件lombok报错问题(亲测有效)

    这篇文章主要介绍了解决IDEA2020.2插件lombok报错问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Java视频断点上传的实现示例

    Java视频断点上传的实现示例

    断点续传指的是在下载或上传时,将下载或上传任务人为的划分为几个部分,本文主要介绍了Java视频断点上传的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-05-05
  • idea手动执行maven命令的三种实现方式

    idea手动执行maven命令的三种实现方式

    这篇文章主要介绍了idea手动执行maven命令的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Java日常练习题,每天进步一点点(38)

    Java日常练习题,每天进步一点点(38)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • Java实现TCP和UDP协议详解

    Java实现TCP和UDP协议详解

    这篇文章主要介绍了Java实现TCP和UDP协议详解,TCP(传输控制协议)和UDP(用户数据报协议)是两种最常用的传输层协议,它们都用于在网络上传输数据,但是它们之间有很多不同之处,需要的朋友可以参考下
    2023-07-07
  • SpringBoot上传文件大小受限问题的解决办法

    SpringBoot上传文件大小受限问题的解决办法

    最近有一次由于项目升级发现了一个上传方面的问题,下面这篇文章主要给大家介绍了关于SpringBoot上传文件大小受限问题的解决办法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • Java实现根据模板自动生成新的PPT

    Java实现根据模板自动生成新的PPT

    这篇文章主要介绍了如何利用Java代码自动生成PPT,具体就是查询数据库数据,然后根据模板文件(PPT),将数据库数据与模板文件(PPT),进行组合一下,生成新的PPT文件。感兴趣的可以了解一下
    2022-02-02
  • java运行shell脚本方法示例

    java运行shell脚本方法示例

    利用Runtime.execute方法,我们可以在Java程序中运行Linux的Shell脚本,或者执行其他程序
    2013-12-12

最新评论