什么是 @Conditional
?
@Conditional
是 Spring 4.0 引入的核心注解,用于根据特定条件决定是否创建某个 Bean 或导入某个配置类。
它位于 Spring 框架的 org.springframework.context.annotation
包中,是实现条件化装配(Conditional Bean Registration) 的基石。
内置条件注解实战(开箱即用)
Spring 提供了多个基于 @Conditional
的便捷注解,直接使用即可:
1. @ConditionalOnProperty
:基于配置属性
@Configuration
public class EmailConfig {
@Bean
@ConditionalOnProperty(
name = "email.enabled",
havingValue = "true",
matchIfMissing = false
)
public EmailService emailService() {
return new SmtpEmailService();
}
}
✅ 只有当 application.yml
中 email.enabled=true
时,才创建 EmailService
。
2. @ConditionalOnClass
:基于类路径存在性
@Configuration
@ConditionalOnClass(RedisTemplate.class)
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
return template;
}
}
✅ 只有当类路径下存在 RedisTemplate
类时(即引入了 spring-boot-starter-data-redis
),才加载此配置。
3. @ConditionalOnMissingBean
:当 Bean 不存在时
@Configuration
public class DataSourceConfig {
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() {
return new HikariDataSource(); // 默认数据源
}
}
✅ 如果用户没有自定义 DataSource
,则使用默认配置;否则,使用用户自定义的。
✅ 这是 Spring Boot 实现“约定优于配置”的关键!
4. @ConditionalOnWebApplication
:判断是否为 Web 环境
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
public class WebConfig {
// 只在 Servlet Web 环境下生效
}
⚠️ 注意事项
事项 | 建议 |
⚠️ 条件判断要轻量 |
|
⚠️ 避免循环依赖 | 条件判断中不要依赖尚未创建的 Bean |
⚠️ 合理使用 | 默认值要符合“最小权限”原则 |
✅ 文档化条件逻辑 | 让团队成员清楚每个条件的含义 |