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

Spring中如何结合@ConfigurationProperties与@Conditional使用?

结合@ConfigurationProperties与@Conditional实现条件化Bean的解决方案

你之前的方案失败的核心原因是:Condition接口的matches方法执行时机早于@ConfigurationProperties注解的Bean初始化流程,此时BeanFactory中还未创建ClientProperties实例,直接调用getBean自然会找不到。

下面提供两种可行的解决方案,既保留@ConfigurationProperties的强类型与重构优势,又实现条件化Bean:

方案一:在自定义Condition中手动绑定属性到Properties类

通过Spring的Binder工具,直接从Environment中读取属性并绑定到ClientProperties实例,无需依赖已初始化的Bean:

  1. 定义带常量前缀的ClientProperties类:
@ConfigurationProperties(prefix = ClientProperties.PREFIX)
public class ClientProperties {
    public static final String PREFIX = "client";
    private boolean secured;

    public boolean isSecured() {
        return secured;
    }

    public void setSecured(boolean secured) {
        this.secured = secured;
    }
}
  1. 修改自定义Condition实现:
public class SecurityEnabledCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ClientProperties props = new ClientProperties();
        // 从Environment绑定属性到实例
        Binder.get(context.getEnvironment())
              .bind(ClientProperties.PREFIX, Bindable.ofInstance(props));
        return props.isSecured();
    }
}
  1. 在配置类中使用该Condition,同时确保ClientProperties可被扫描为Bean(如果需要作为Bean使用):
@Configuration
@ConfigurationPropertiesScan // 扫描@ConfigurationProperties注解的类
public class SecurityConfig {
    @Conditional(SecurityEnabledCondition.class)
    @Bean
    public SecurityBean securityBean() {
        return new SecurityBean();
    }
}

方案二:使用@ConditionalOnExpression直接引用Properties Bean属性(更简洁)

无需自定义Condition,直接通过Spring Boot的表达式条件绑定ClientProperties的属性:

  1. 确保ClientProperties被注册为Bean,可通过@EnableConfigurationProperties或@ConfigurationPropertiesScan实现:
@Configuration
@EnableConfigurationProperties(ClientProperties.class)
public class SecurityConfig {
    @Bean
    // 通过spel表达式直接引用ClientProperties的属性
    @ConditionalOnExpression("#{clientProperties.secured}")
    public SecurityBean securityBean() {
        return new SecurityBean();
    }
}

这里的clientProperties是Spring自动生成的Bean名称(类名首字母小写),若需自定义名称,可在ClientProperties上添加@Component("customName")或通过@Bean方法指定。

这种方式完全依托@ConfigurationProperties的强类型特性,重构时只需修改ClientProperties的属性名,同步调整spel表达式中的对应字段即可,无需接触原始配置键名。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 16:12:37