You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中@ConditionalOnProperty正则前缀匹配的正确实现

解决Spring Boot中基于数组格式属性启用配置类的问题

首先明确:@ConditionalOnProperty的prefix参数不支持正则表达式,它仅用于指定固定的属性前缀,所以你用^sites\[.*\].*这种写法肯定不会生效。下面给你几个实用的解决方案:

方案一:自定义Condition类(精准控制判断逻辑)

自己实现Spring的Condition接口,通过Environment遍历所有属性键,匹配sites[数字].id这种格式的属性。

代码实现

  1. 编写自定义Condition:
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.env.Environment;
import java.util.regex.Pattern;

public class OnSitesIdExistsCondition implements Condition {
    // 匹配sites[0].id、sites[1].id这类格式的正则
    private static final Pattern SITE_ID_PATTERN = Pattern.compile("^sites\\[\\d+\\]\\.id$");

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment env = context.getEnvironment();
        // 遍历所有属性键,找到匹配的就返回true
        for (String propName : env.getPropertyNames()) {
            if (SITE_ID_PATTERN.matcher(propName).matches()) {
                return true;
            }
        }
        return false;
    }
}
  1. 在配置类上使用该Condition:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
@Conditional(OnSitesIdExistsCondition.class)
public class TestConfiguration {

    @Bean
    public TestManager testManager() {
        return new TestManager();
    }
}

方案二:使用@ConditionalOnExpression(更简洁)

不想写自定义类的话,直接用@ConditionalOnExpression结合SpEL表达式,一行代码完成判断:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionalOnExpression;
import org.springframework.context.annotation.Configuration;

@Configuration
// 用SpEL遍历所有属性,匹配目标格式
@ConditionalOnExpression("#{environment.getPropertyNames().stream().anyMatch(name -> name matches '^sites\\[\\d+\\]\\.id$')}")
public class TestConfiguration {

    @Bean
    public TestManager testManager() {
        return new TestManager();
    }
}

这个方案代码量少,适合不需要额外逻辑的简单场景。

方案三:结合@ConfigurationProperties(适合需使用属性内容的场景)

如果你的sites是数组/列表结构,后续还要用到这些属性值,可以先通过@ConfigurationProperties绑定属性,再判断是否存在有效的id字段:

代码实现

  1. 定义属性绑定类:
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;

@ConfigurationProperties(prefix = "sites")
public class SiteProperties {
    private List<Site> list;

    public static class Site {
        private String id;
        // 必须添加getter和setter
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
    }

    public List<Site> getList() { return list; }
    public void setList(List<Site> list) { this.list = list; }
}
  1. 在配置类中使用:
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(SiteProperties.class)
public class TestConfiguration {

    @Bean
    @Conditional(OnValidSiteCondition.class)
    public TestManager testManager(SiteProperties siteProperties) {
        // 可直接使用siteProperties中的属性内容
        return new TestManager();
    }

    // 内部类实现Condition,判断是否存在带有效id的site
    static class OnValidSiteCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            SiteProperties props = context.getBeanFactory().getBean(SiteProperties.class);
            return props.getList() != null && !props.getList().isEmpty()
                    && props.getList().stream().anyMatch(site -> site.getId() != null);
        }
    }
}

这个方案不仅能判断属性是否存在,还能验证属性有效性,适合需要操作这些属性的场景。


内容的提问来源于stack exchange,提问作者Abhilash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 20:40:29