当前位置: 首页 > ops >正文

SpringBoot中的条件注解

文章目录

  • 前言
  • 什么是条件注解
  • 核心原理
  • 常用条件注解详解
    • 1. @ConditionalOnClass和@ConditionalOnMissingClass
    • 2. @ConditionalOnBean和@ConditionalOnMissingBean
    • 3. @ConditionalOnProperty
  • 应用场景:多数据源配置
  • 在SpringBoot自动配置中的核心作用
    • 自动配置的工作原理
    • 经典自动配置示例分析
  • 总结

前言

在SpringBoot开发中,我们经常会遇到这样的场景:某些Bean只有在特定条件下才需要被创建,或者根据不同的环境加载不同的配置。SpringBoot的条件注解就是为了解决这类问题而设计的。

什么是条件注解

条件注解是SpringBoot提供的一套机制,允许我们根据特定条件来决定是否创建Bean、加载配置或执行某些逻辑。这些注解基于Spring 4.0引入的@Conditional注解,SpringBoot在此基础上扩展了更多实用的条件注解。

核心原理

所有的条件注解都基于@Conditional注解,该注解需要指定一个Condition接口的实现类。Condition接口只有一个方法:

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

当Spring容器加载Bean时,会调用这个方法来判断条件是否满足。如果返回true,则创建Bean;如果返回false,则跳过。

常用条件注解详解

1. @ConditionalOnClass和@ConditionalOnMissingClass

这两个注解用于检查类路径中是否存在指定的类。

@Configuration
public class DatabaseConfig {// 当类路径中存在DataSource类时才创建这个Bean@Bean@ConditionalOnClass(DataSource.class)public DataSource dataSource() {return new HikariDataSource();}// 当类路径中不存在Redis相关类时才创建内存缓存@Bean@ConditionalOnMissingClass("org.springframework.data.redis.core.RedisTemplate")public CacheManager memoryCache() {return new ConcurrentMapCacheManager();}
}

2. @ConditionalOnBean和@ConditionalOnMissingBean

这两个注解根据Spring容器中是否存在指定的Bean来决定是否创建。

@Configuration
public class ServiceConfig {// 当容器中存在UserRepository Bean时才创建UserService@Bean@ConditionalOnBean(UserRepository.class)public UserService userService(UserRepository userRepository) {return new UserServiceImpl(userRepository);}// 当容器中不存在CacheManager时才创建默认的@Bean@ConditionalOnMissingBean(CacheManager.class)public CacheManager defaultCacheManager() {return new NoOpCacheManager();}
}

3. @ConditionalOnProperty

根据配置属性来决定是否创建Bean,这是最常用的条件注解之一。

@Configuration
public class FeatureConfig {// 当spring.feature.enabled=true时才启用这个功能@Bean@ConditionalOnProperty(prefix = "spring.feature",name = "enabled",havingValue = "true",matchIfMissing = false // 默认false,即属性不存在时不匹配)public FeatureService featureService() {return new FeatureServiceImpl();}
}

应用场景:多数据源配置

@Configuration
public class DataSourceConfig {@Primary@Bean@ConditionalOnProperty(name = "app.datasource.primary.enabled", havingValue = "true")public DataSource primaryDataSource() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/primary").build();}@Bean@ConditionalOnProperty(name = "app.datasource.secondary.enabled", havingValue = "true")public DataSource secondaryDataSource() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/secondary").build();}
}

在SpringBoot自动配置中的核心作用

SpringBoot的自动配置是其最核心的特性之一,而条件注解正是自动配置得以智能化的关键所在。让我们深入了解条件注解在自动配置中是如何发挥作用的。

自动配置的工作原理

SpringBoot通过spring.factories文件定义了所有的自动配置类,启动时会加载这些配置。但是,并不是所有的配置都应该被激活,这就需要条件注解来控制。

# META-INF/spring.factories示例
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration

经典自动配置示例分析

让我们看看SpringBoot内置的一些自动配置是如何使用条件注解的:

  1. RedisAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)  // Redis类存在时才配置
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {@Bean@ConditionalOnMissingBean(name = "redisTemplate")  // 用户没有自定义时才创建@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);return template;}@Bean@ConditionalOnMissingBean@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {return new StringRedisTemplate(redisConnectionFactory);}
}
  1. DataSourceAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "javax.sql.DataSource")  // 没有数据源时才自动配置
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {@Configuration(proxyBeanMethods = false)@Conditional(EmbeddedDatabaseCondition.class)  // 自定义条件判断@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import(EmbeddedDataSourceConfiguration.class)protected static class EmbeddedDatabaseConfiguration {}@Configuration(proxyBeanMethods = false)@Conditional(PooledDataSourceCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import({ HikariConfiguration.class, TomcatConfiguration.class,DbcpConfiguration.class, OracleUcpConfiguration.class,GenericConfiguration.class, DataSourceJmxConfiguration.class })protected static class PooledDataSourceConfiguration {}
}

总结

SpringBoot的条件注解是一个非常强大的特性,它让我们能够构建更加灵活和智能的应用程序。通过合理使用这些注解,不仅能让我们写出更优雅的代码,也能让我们的应用在面对不同场景时表现得更加智能。希望这篇文章能帮助大家更好地理解和使用SpringBoot的条件注解。

http://www.xdnf.cn/news/18397.html

相关文章:

  • 工作后的总结和反思1
  • 如何制定股指期货投机交易策略计划?
  • 数字社会学是干什么的?数字社会学理论与数字社会学家唐兴通讲数字社会学书籍有哪些?AI社会学人工智能社会学理论框架
  • 使用jwt+redis实现单点登录
  • LeetCode 回文链表
  • 力扣1005:k次取反后最大化的数组和
  • Elasticsearch官方文档学习-未完待续
  • 三层交换机
  • Bartender 5 多功能菜单栏管理(Mac电脑)
  • 【学习嵌入式day-29-网络】
  • 深入解析C++非类型模板参数
  • 网络打印机自动化部署脚本
  • 软考 系统架构设计师系列知识点之杂项集萃(130)
  • 记录前端菜鸟的日常——小程序内嵌H5页面自定义分享按钮
  • 深入解析HashMap的存储机制:扰动函数、哈希计算与索引定位
  • 信息收集4----(收集网站指纹信息)
  • 20250821 圆方树总结
  • 一、部署LNMP
  • 实现自己的AI视频监控系统-第一章-视频拉流与解码3
  • mac的m3芯使用git
  • 18维度解密·架构魔方:一览无遗的平衡艺术
  • LT8712SX,Type-C/DP1.4 /eDP转 DP1.4/HD-DVI2.0 带音频
  • AXI GPIO S——ZYNQ学习笔记10
  • Java项目:基于SpringBoot和VUE的在线拍卖系统(源码+数据库+文档)
  • K 均值聚类(K-Means)演示,通过生成笑脸和爱心两种形状的模拟数据,展示了无监督学习中聚类算法的效果。以下是详细讲解:
  • 【typenum】 19 类型相同检查(type_operators.rs片段)
  • JavaWeb前端03(Ajax概念及在前端开发时应用)
  • SD 节点学习
  • ZStack Zaku替代VMware Tanzu:六项对比、构建虚拟机+容器一体化架构
  • HTTP 403 错误:后端权限校验机制深度解析