Quarkus环境下编程式选择CDI Bean失败 抛出未找到匹配Bean的异常
报错根因与修复方案
编程式通过CDI.current().select()选择Bean的写法本身是Quarkus完全支持的,你遇到的「未找到匹配所需类型[接口org.business.CommonnInterface]和限定符[[@org.cdi.Report(value=ONE)]]的Bean」报错,核心原因是对应的实现类根本没有被Quarkus内置的CDI实现(Arc)纳入托管Bean集合,具体问题和修复方式如下:
常见问题诱因
- 仅在实现类上打自定义限定符
@Report无法让容器识别为托管Bean。按照CDI规范,自定义Qualifier只是用于缩小Bean匹配范围的标记,不属于Bean定义注解,容器不会把没有任何Bean定义注解(比如带作用域语义的@ApplicationScoped、@Dependent、@RequestScoped等)的类自动扫描为可注入的Bean。 - 跨版本包名不匹配:Quarkus 3.x及以上版本默认使用Jakarta CDI命名空间,如果自定义限定符时错导入了老版本javax包路径下的注解,容器不会把
@Report识别为合法的CDI限定符,即使Bean被扫描到,也会因为限定符类型不合法导致匹配失败。 - 限定符字面量导入错误:用于编程式匹配的
AnnotationLiteral如果错导入老版本javax包路径下的实现,会导致和类上标记的限定符无法完成等值匹配。
具体修复步骤
- 给
ReportOneBusiness类补充明确的作用域注解,最常用的单例作用域写法示例:@Report(value = ReportType.ONE) @ApplicationScoped public class ReportOneBusiness implements CommonnInterface { @Override public void call() { System.out.println("Hello"); } } - 核查所有CDI相关注解的导入路径,确保和当前使用的Quarkus版本匹配:
- 自定义
@Report上标记的@Qualifier导入jakarta.inject.Qualifier Literal类继承的AnnotationLiteral导入jakarta.enterprise.util.AnnotationLiteral- 作用域注解导入
jakarta.enterprise.context.ApplicationScoped
- 自定义
- 分步验证扫描结果:可以先不传限定符,仅按接口类型查询,确认容器能识别到对应的实现类:
如果这一步仍然报找不到Bean,说明类没有被扫描为托管Bean,优先检查类的包路径是否在Quarkus应用的根扫描包下,以及作用域注解是否添加正确。CommonnInterface commonnInterface = CDI.current() .select(CommonnInterface.class) .get();
内容的提问来源于stack exchange,提问作者Leandro Jordao
相关产品推荐
相关产品推荐

