🌟 核心注解详解
1. @ConditionalOnProperty - 基于属性的条件判断
<JAVA>
// 检查配置文件中是否存在指定属性
@ConditionalOnProperty(name = "myapp.feature.enabled", havingValue = "true")
public class MyService {
// 只有当 myapp.feature.enabled=true 时才会创建该Bean
}
常用参数:
name: 属性名(如myapp.feature.enabled)havingValue: 预期值(如true)matchIfMissing: 如果属性不存在时是否匹配(默认false)
<JAVA>
// 多种用法示例
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
@ConditionalOnProperty(name = "database.type", havingValue = "mysql")
@ConditionalOnProperty(name = "logging.level", havingValue = "debug", matchIfMissing = true)
2. @ConditionalOnClass - 基于类路径的条件判断
<JAVA>
// 当类路径中存在特定类时才创建Bean
@ConditionalOnClass(DataSource.class)
public class DataSourceConfig {
// 只有在引入了数据库相关依赖时才会生效
}
典型应用场景:
- 数据库配置:仅当 JDBC 驱动存在时启用
- Redis 配置:仅当 Redis 客户端存在时启用
- Elasticsearch 配置:仅当 Elasticsearch 客户端存在时启用
3. @ConditionalOnMissingClass - 类路径缺失时的条件判断
<JAVA>
// 当类路径中不存在特定类时才创建Bean
@ConditionalOnMissingClass("com.example.MyLegacyClass")
public class DefaultConfig {
// 如果没有使用旧版类,就使用默认配置
}
🔍 其他重要条件化注解
4. @ConditionalOnMissingBean - 缺失Bean时的条件判断
<JAVA>
// 只有当前容器中没有该类型的Bean时才创建
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() {
return new HikariDataSource();
}
应用场景:
- 提供默认实现,但允许用户自定义覆盖
- 避免重复配置冲突
5. @ConditionalOnWebApplication - Web应用环境判断
<JAVA>
// 仅在Web应用环境中生效
@ConditionalOnWebApplication(type = Type.SERVLET)
public class WebConfig {
// 只在Spring MVC应用中生效
}
6. @ConditionalOnNotWebApplication - 非Web应用环境判断
<JAVA>
// 仅在非Web应用环境中生效
@ConditionalOnNotWebApplication
public class CommandLineRunnerConfig {
// 只在命令行应用中生效
}
7. @ConditionalOnExpression - 表达式条件判断
<JAVA>
// 使用SpEL表达式进行复杂条件判断
@ConditionalOnExpression("${feature.new-ui:false} == true")
public class NewUiConfig {
// 只有在配置为true时才生效
}
8. @ConditionalOnResource - 资源存在性判断
<JAVA>
// 检查特定资源文件是否存在
@ConditionalOnResource(resources = "classpath:config/app.properties")
public class AppConfig {
// 只有配置文件存在时才加载
}
🧩 组合使用场景
场景1:数据库配置(典型组合)
<JAVA>
@Configuration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.url", matchIfMissing = false)
public class DatabaseConfig {
@Bean
@Primary
public DataSource dataSource() {
return new HikariDataSource();
}
}
场景2:缓存配置
<JAVA>
@Configuration
@ConditionalOnClass(CacheManager.class)
@ConditionalOnMissingBean(CacheManager.class)
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new CaffeineCacheManager();
}
}
🎯 选择建议
| 场景 | 推荐注解 |
|---|---|
| 检查配置属性 | @ConditionalOnProperty |
| 检查依赖是否存在 | @ConditionalOnClass/@ConditionalOnMissingClass |
| 检查Bean是否存在 | @ConditionalOnMissingBean |
| 判断应用类型 | @ConditionalOnWebApplication/@ConditionalOnNotWebApplication |
| 复杂逻辑判断 | @ConditionalOnExpression |
💡 总结
这些条件化注解是 Spring Boot 自动配置机制的核心,它们确保:
- 避免配置冲突:只有在合适条件下才创建Bean
- 提高灵活性:用户可以轻松覆盖默认配置
- 保持轻量化:不相关的功能不会被加载
- 增强可维护性:清晰的条件关系便于理解和调试
理解这些注解的使用,是掌握 Spring Boot 自动配置机制的关键一步。