Spring Boot中@ConditionalOnProperty不支持多值匹配,需用SpEL表达式或自定义条件注解实现:如#{ @environment.getProperty('feature.mode') != null && @environment.getProperty('feature.allowed-modes').split(',').contains(@environment.getProperty('feature.mode')) },或封装@ConditionalOnMultiProperty注解。

在Spring Boot中配置@ConditionalOnProperty注解支持多个属性值判断,避免因只写单个value导致条件不生效或启动失败。
用havingValue指定多值匹配
在@ConditionalOnProperty中直接传入String数组,让Spring判断任意一个值为true时就启用Bean。
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true,debug,preview")
这行代码会失败——【havingValue不支持逗号分隔的字符串】,它只接受单一布尔值或字符串字面量。
用matchIfMissing配合多个独立注解
Spring不支持单个@ConditionalOnProperty声明多个不同key的逻辑或判断,必须拆成多个条件组合。
@ConditionalOnProperty(name = "feature.mode", havingValue = "dev")
@ConditionalOnProperty(name = "feature.mode", havingValue = "test")
@ConditionalOnProperty(name = "feature.mode", havingValue = "staging")
这样写会报错——【重复注解不被Java 8之前的版本支持】,且Spring不允许多个同类型条件注解叠加生效。
用SpEL表达式动态判断多值
这是最稳妥的方式:把多个合法值写进配置项,用SpEL做集合包含判断。
第一步:在application.yml里定义允许的模式列表:
feature:
mode: dev
allowed-modes: [dev, test, staging]
第二步:在@Bean方法上使用SpEL引用该列表并判断当前mode是否在其中:
@ConditionalOnExpression("#{ @environment.getProperty('feature.mode') != null && @environment.getProperty('feature.allowed-modes').split(',').contains(@environment.getProperty('feature.mode')) }")
注意:split(',')要求yml中allowed-modes必须写成逗号分隔字符串而非YAML数组,否则getProperty返回的是toString结果,形如"[dev, test, staging]",无法直接split。
第三步:改用JSON格式存储列表更可靠:
feature:
mode: dev
allowed-modes: '["dev","test","staging"]'
然后SpEL改为:#{ T(com.fasterxml.jackson.databind.ObjectMapper).readValue(@environment.getProperty('feature.allowed-modes'), T(java.util.List).class).contains(@environment.getProperty('feature.mode')) }
封装成自定义条件注解
方法一:继承Spring的Condition接口,手动解析配置值
创建类MultiValuePropertyCondition implements Condition,在matches()里读取environment.getProperty("feature.modes"),用Arrays.asList(...split(",")).contains(current)判断。
方法二:用@Conditional组合多个@ConditionalOnProperty
定义一个组合注解@ConditionalOnMultiProperty:
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MultiValuePropertyCondition.class)
public @interface ConditionalOnMultiProperty {
String name();
String[] values() default {};
}
然后在需要的地方直接写:
@ConditionalOnMultiProperty(name = "feature.mode", values = {"dev", "test", "staging"})
















