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

Spring Boot中如何通过ConditionalOnProperty注解条件注入父/子类组件

问题分析

当配置startup=1时出现bean冲突,是因为BaseServiceImpl的条件注解没有正确排除startup为1或2的场景,导致父类和对应子类的bean同时被Spring实例化,容器中存在多个IBaseService类型的bean,无法确定注入哪个。

解决方案

以下三种方案都能实现需求,按需选择:

方案一:用@ConditionalOnExpression精准控制父类bean的创建时机

修改BaseServiceImpl的注解,让它仅在startup为空、不存在或非1/2值时被创建:

@Service
@ConditionalOnExpression("${startup:} != '1' && ${startup:} != '2'")
public class BaseServiceImpl implements IBaseService {
    @Override
    public void say() {
        System.out.println("default say");
    }
}

两个子类保持原有注解不变:

@Service
@ConditionalOnProperty(name = "startup", havingValue = "1")
public class CustomService1Impl extends BaseServiceImpl{
    @Override
    public void say() {
        System.out.println("custom 1");
    }
}

@Service
@ConditionalOnProperty(name = "startup", havingValue = "2")
public class CustomService2Impl extends BaseServiceImpl{
    @Override
    public void say() {
        System.out.println("custom 2");
    }
}

方案二:用@ConditionalOnMissingBean避免父类与子类bean共存

给BaseServiceImpl添加@ConditionalOnMissingBean注解,确保当有其他IBaseService实现类的bean存在时,父类bean不被实例化:

@Service
@ConditionalOnProperty(name = "startup", havingValue = "", matchIfMissing = true)
@ConditionalOnMissingBean(IBaseService.class)
public class BaseServiceImpl implements IBaseService {
    @Override
    public void say() {
        System.out.println("default say");
    }
}

子类注解保持不变,这样当startup=1或2时,对应子类bean被创建,BaseServiceImpl会因已有同类型bean而不被实例化。

方案三:自定义Condition类实现灵活判断

创建自定义Condition类,判断startup的值是否为1或2:

public class StartupNot1Or2Condition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String startupValue = context.getEnvironment().getProperty("startup");
        return startupValue == null || startupValue.isEmpty() || (!"1".equals(startupValue) && !"2".equals(startupValue));
    }
}

给BaseServiceImpl添加@Conditional注解关联自定义条件:

@Service
@Conditional(StartupNot1Or2Condition.class)
public class BaseServiceImpl implements IBaseService {
    @Override
    public void say() {
        System.out.println("default say");
    }
}

子类保持原有配置即可。

验证效果
  • 不配置startup或配置startup=时,仅BaseServiceImpl被注入;
  • 配置startup=1时,仅CustomService1Impl被注入;
  • 配置startup=2时,仅CustomService2Impl被注入;
  • 配置startup为其他值(如3)时,仅BaseServiceImpl被注入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:04:57