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

如何让自定义配置值可在@ConditionalOnExpression注解中正常读取

问题根因

@ConditionalOnExpression 属于Spring条件注解,执行时机远早于普通Bean的实例化阶段:它在Bean定义注册的阶段就会执行SpEL表达式判断是否要注册对应Bean,此时你的FunctionalityConfig实例还没有被初始化并注册到Spring容器中,因此表达式找不到functionalityConfig这个Bean对象,触发EL1008E报错。
而你在Application类中使用的@Value是Bean实例化完成后的属性注入阶段才执行的,此时FunctionalityConfig已经完成初始化,所以可以正常读取到值。

解决方案

方案1:直接读取配置属性(推荐)

@ConditionalOnExpression可以直接读取环境中的配置参数,不需要依赖FunctionalityConfig Bean,修改注解中的SpEL表达式即可:

@ConditionalOnExpression("${com.example.config.functionality.rest-interface:false}")

注意Spring配置默认采用kebab-case命名规则,驼峰的restInterface对应配置中的rest-interface,末尾的:false表示找不到对应配置时默认值为false。

方案2:自定义Condition实现

如果需要更灵活的判断逻辑,可以放弃@ConditionalOnExpression,自己实现Condition接口:
首先定义条件类:

public class OnRestInterfaceCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment()
                .getProperty("com.example.config.functionality.rest-interface", Boolean.class, false);
    }
}

然后修改自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional(OnRestInterfaceCondition.class)
public @interface ConditionalOnRestInterface {
}

这个方案执行效率和稳定性都更高,也不需要依赖FunctionalityConfig的初始化时机。

额外优化点

你的FunctionalityConfig上不需要同时加@Configuration和@ConfigurationProperties,如果已经在启动类加了@EnableConfigurationProperties(FunctionalityConfig.class),去掉@Configuration注解即可,避免重复注册Bean。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:27:01