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

如何创建需依赖注入的Spring自定义Condition?

问题分析

Spring的@Conditional注解在Bean注册阶段执行逻辑,此时IoC容器还未完成普通Bean的实例化和依赖注入。当你给@Conditional传入FavoriteColorsAreCoolCondition.class时,Spring会直接通过反射实例化这个Condition类,而非从容器中获取你注册的Condition Bean——这就是为什么你即使注册了Condition Bean,依然会收到"缺少默认构造函数"的报错。

同时,你的IFavoriteColorFinder依赖在Bean注册阶段还未被实例化,无法通过构造函数注入到Condition中,这是Spring生命周期的固有限制。

可行解决方案

方案一:通过ConditionContext获取BeanFactory延迟获取依赖

利用ConditionContext提供的BeanFactory,通过BeanProvider延迟获取依赖Bean,既避免了过早初始化的问题,也不需要给Condition添加无参构造。

修改后的Condition代码:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.beans.factory.BeanProvider;

public final class FavoriteColorsAreCoolCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 获取BeanProvider,支持安全、延迟获取Bean实例
        BeanProvider<IFavoriteColorFinder> colorFinderProvider = 
            context.getBeanFactory().getBeanProvider(IFavoriteColorFinder.class);
        
        // 检查依赖Bean是否存在,再执行判断逻辑
        IFavoriteColorFinder colorFinder = colorFinderProvider.getIfAvailable();
        if (colorFinder != null) {
            String favoriteColor = colorFinder.findFavoriteColor();
            return "red".equalsIgnoreCase(favoriteColor);
        }
        // 依赖不存在时的默认返回值,可根据需求调整
        return false;
    }
}

配置类只需保留依赖Bean和带@Conditional的Bean:

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

@Configuration
public class CompositionRootJavaConfig {

    @Bean
    public IFavoriteColorFinder getAnIFavoriteColorFinder() {
        return new FirstConcreteIFavoriteColorFinder();
    }

    @Conditional(FavoriteColorsAreCoolCondition.class)
    @Bean
    public ArithmeticException addArithmeticException() {
        return new ArithmeticException("This exists to test if FavoriteColorsAreCoolCondition works or not");
    }
}

方案二:使用ConfigurationCondition控制执行时机

如果你的依赖Bean在其他配置类中,需要确保依赖先被注册,可以实现ConfigurationCondition接口,指定Condition的执行时机为REGISTER_BEAN阶段(即所有Bean定义注册完成后),进一步保证依赖Bean的定义已存在。

代码示例:

import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.ConfigurationCondition;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.beans.factory.BeanProvider;

public final class FavoriteColorsAreCoolCondition implements ConfigurationCondition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        BeanProvider<IFavoriteColorFinder> colorFinderProvider = 
            context.getBeanFactory().getBeanProvider(IFavoriteColorFinder.class);
        
        IFavoriteColorFinder colorFinder = colorFinderProvider.getIfAvailable();
        if (colorFinder != null) {
            String favoriteColor = colorFinder.findFavoriteColor();
            return "red".equalsIgnoreCase(favoriteColor);
        }
        return false;
    }

    @Override
    public ConfigurationPhase getConfigurationPhase() {
        // 指定在Bean注册完成后执行Condition判断
        return ConfigurationPhase.REGISTER_BEAN;
    }
}
关键注意事项
  • 不要尝试给Condition添加构造函数依赖,也无需注册Condition为Bean——@Conditional只会直接实例化你传入的Class类型,不会使用容器中的Condition实例。
  • 使用BeanProvider而非直接调用getBean(),避免因依赖Bean未初始化导致的异常,getIfAvailable()会在Bean不存在时返回null,更安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:44:50