当将 @Profile与自定义Condition组合使用时,Spring Boot的 @Conditional Bean未被拾取 — NoSuchBeanDefinitionException

后端开发 2026-07-09

问题

我正在构建一个Spring Boot应用,其中一个 TreeRepository bean必须在两个条件同时满足时被激活:一个Spring @Profile 和一个自定义 @Conditional。存储库定义如下:

java

@Repository
@Profile("mongo")
@Conditional(MongoCondition.class)
@Primary
public class MongoTreeRepository implements TreeRepository {
    // ...
}

MongoCondition 读取一个名为properties的属性

public class MongoCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String repoType = context.getEnvironment().getProperty("app.storage");
        return "mongo".equalsIgnoreCase(repoType);
    }
}

我的 application-mongo.properties 设置:

properties

spring.profiles.active=mongo
app.storage=mongo

观察到的行为

当同时存在 @Profile("mongo")@Conditional(MongoCondition.class) 时,应用在启动阶段有时会因为 NoSuchBeanDefinitionException: No qualifying bean of type 'TreeRepository' 而失败,尽管活动的配置文件是 mongo,且 app.storage=mongo 已被设置。移除任一注解即可使其正常工作。

期望的行为

两个注解都应该评估为 true,并且bean应按正常方式注册。

我尝试过

  • 通过在 ApplicationRunner 中打印来验证该属性已正确加载
  • 尝试用第二个 @Conditional 替换 @Profile,手动检查活动配置文件——结果偶尔仍然相同
  • 检查了循环依赖——未发现循环依赖

问题

在Spring Boot中,@Profile@Conditional 的评估之间是否存在已知的排序问题?我是否应该将两者的检查合并到一个 Condition 类中以避免冲突?@Primary 是否会与条件评估互动?

解决方案

从你的问题来看,你说 spring.profiles.active=mongo 已在 application-mongo.properties 中被设置。这存在问题,因为根据 文档 这被认为是无效的:

spring.profiles.activespring.profiles.default 只能在非配置文件相关的文档中使用。这意味着它们不能被包含在 profile specific files 或由 spring.config.activate.on-profile 启用的文档中。

在Spring Boot中,@Profile与 @Conditional的评估之间是否存在已知的排序问题?

没有,不存在排序问题。@Profile 实现为一个 @Conditional请参阅它的源代码。按你预期的行为,“这两个注解都应当评估为true,bean应该正常注册”。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章