Spring中如何实现基于config.*前缀可变子属性的配置类条件初始化
这个场景我太熟了——@ConditionalOnProperty确实没法直接搞定带可变子键的前缀检查,毕竟它只能盯死具体的属性名。给你三个实用的解决思路,一步步来:
思路一:自定义Condition实现最灵活的检查
这是最通用的方案,完全自定义检查逻辑:
- 写一个Condition类,遍历环境里的所有属性,判断是否存在
config.前缀的键:
public class HasConfigPrefixCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getEnvironment(); // 遍历所有属性名,找到任何以config.开头的就返回true for (String propName : env.getPropertyNames()) { if (propName.startsWith("config.")) { return true; } } return false; } }
- 然后在你的配置类上加上
@Conditional(HasConfigPrefixCondition.class):
@Configuration @Conditional(HasConfigPrefixCondition.class) public class MyConfiguration { private Map<String, KEY> config = new HashMap<>(); // 别忘了加这个注解绑定YML里的配置哦 @ConfigurationProperties(prefix = "config") public void setConfig(Map<String, KEY> config) { this.config = config; } }
思路二:用@ConditionalOnExpression写一行搞定
不想写额外类的话,直接用SpEL表达式在注解里搞定:
@Configuration @ConditionalOnExpression("#{environment.getPropertyNames().stream().anyMatch(p -> p.startsWith('config.'))}") @ConfigurationProperties(prefix = "config") public class MyConfiguration { private Map<String, KEY> config = new HashMap<>(); // setter或者直接用@Autowired注入都行,看你习惯 public void setConfig(Map<String, KEY> config) { this.config = config; } }
这个表达式会直接遍历环境中的所有属性,只要有一个以config.开头,就会初始化这个配置类。
额外提醒
- 不管用哪个方案,
@ConfigurationProperties(prefix = "config")是必须的,不然Spring没法把YML里的配置绑定到你的Map上。 - 如果YML里只写了
config:但下面没有任何子属性,这两个方案都会返回false,不会初始化配置类,完全符合你的需求。
内容的提问来源于stack exchange,提问作者sge
相关产品推荐
相关产品推荐

