一、属性配置类(最常用)
1. @ConditionalOnProperty
你已经在用,根据配置文件属性匹配
java
// 存在且等于true,缺失也生效
@ConditionalOnProperty(name = "redis.enabled", havingValue = "true", matchIfMissing = true)
2. @ConditionalOnExpression
SpEL 表达式判断,支持多条件与或、复杂逻辑
java
@ConditionalOnExpression("'${redis.enabled:true}'=='true'")
3. @ConditionalOnJava
基于 JDK 版本条件
java
// JDK8及以上才创建Bean
@ConditionalOnJava(range = ConditionalOnJava.Range.EIGHT_OR_NEWER)
二、Bean / 类存在判断(依赖类是否存在)
1. @ConditionalOnClass
类路径存在指定类才实例化当前 Bean(自动装配核心)
java
// 存在RedisTemplate类才加载当前配置
@ConditionalOnClass(RedisTemplate.class)
2. @ConditionalOnMissingClass
不存在指定类才创建 Bean
java
// 没有RabbitTemplate时才启用简易消息实现
@ConditionalOnMissingClass("org.springframework.amqp.rabbit.core.RabbitTemplate")
3. @ConditionalOnBean
容器中已经存在指定 Bean 才创建当前类
java
@ConditionalOnBean(RedisConnectionFactory.class)
4. @ConditionalOnMissingBean
容器没有对应 Bean 才创建(自定义覆盖默认实现核心)
java
// 用户没自定义RedisTemplate,才用系统默认配置
@ConditionalOnMissingBean(RedisTemplate.class)
框架默认实现,用户自定义则覆盖
java
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserBeanConfig {
@Bean
@ConditionalOnMissingBean
public UserService userService(){
// 用户没自己注入UserService,才使用这个默认实现
return new DefaultUserService();
}
}
5. @ConditionalOnSingleCandidate
容器中只有一个候选 Bean 时才生效
java
@ConditionalOnSingleCandidate(DataSource.class)
三、资源 / 文件、系统环境判断
1. @ConditionalOnResource
classpath 存在指定文件才生效
java
@ConditionalOnResource(resources = "META-INF/my-starter.yml")
2. @ConditionalOnWebApplication
当前是 Web 环境才创建 Bean
可选类型:ANY/SERVLET/REACTIVE
java
// Servlet Web环境才加载
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
3. @ConditionalOnNotWebApplication
非 Web 环境(纯定时任务、客户端)才创建 Bean
java
@ConditionalOnNotWebApplication
4. @ConditionalOnCloudPlatform
判断云平台(K8s、Heroku、Cloud Foundry)
java
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
5. @ConditionalOnSystemProperty
读取系统环境变量(System.getProperty)判断
java
// 系统属性env=dev才生效
@ConditionalOnSystemProperty(name = "env", value = "dev")
6. @ConditionalOnSystemEnvironment
读取操作系统环境变量(OS 环境变量)
java
@ConditionalOnSystemEnvironment(name = "SERVER_MODE", havingValue = "prod")
四、配置分组、分层注解(组合条件)
1. @AutoConfigureAfter / @AutoConfigureBefore
控制自动装配执行顺序,不是条件,但常配合条件注解使用
java
// 在Redis自动配置之后再加载当前类
@AutoConfigureAfter(RedisAutoConfiguration.class)
2. @AutoConfigureOrder
指定装配优先级数字,数值越小越先执行
五、通用自定义条件(底层基础)
@Conditional
Spring 底层通用注解,传入自定义 Condition 实现类
上面所有 @ConditionalOnXxx 底层都是基于它封装
第一步:自定义条件类
java
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class MyCustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 读取配置判断
String enable = context.getEnvironment().getProperty("demo.custom.enable");
return "true".equals(enable);
}
}
第二步:使用
java
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
@Conditional(MyCustomCondition.class)
public class CustomConditionConfig {
}
六、简单使用场景区分建议
-
开关配置控制:
@ConditionalOnProperty(优先) -
多条件复杂逻辑:
@ConditionalOnExpression -
依赖第三方类存在才加载:
@ConditionalOnClass -
给用户留自定义扩展:
@ConditionalOnMissingBean -
Web / 非 Web 环境区分:
@ConditionalOnWebApplication/@ConditionalOnNotWebApplication -
判断文件资源:
@ConditionalOnResource -
系统环境变量区分:
@ConditionalOnSystemProperty -
复杂逻辑自定义 →
@Conditional + 自定义 Condition