Quarkus构建步骤中泛型合成Bean注入失败问题求助
问题场景
尝试创建List<Class<?>>类型的合成Bean,代码如下:
syntheticBeanProducer.produce( SyntheticBeanBuildItem.configure(List.class) .scope(Singleton.class) .addType(com.crv.jms.Util.createType()) .unremovable() .addQualifier().annotation(Identifier.class).addValue("value", name).done() .createWith( recorder.createSupportedEventTypesList(supportedEventTypes)) .unremovable() .done() );
随后在另一个合成Bean中声明对该Bean的依赖:
syntheticBeanProducer.produce( SyntheticBeanBuildItem.configure(EventProducer.class) .addType(EventProducer.class) .scope(Singleton.class) .setRuntimeInit() .addInjectionPoint( com.crv.jms.Util.createType(), AnnotationInstance.builder(Identifier.class).add("value", name).build() ) .addQualifier().annotation(Identifier.class).addValue("value", name).done() .createWith(recorder.createParallelEventProducer(name, topicName)) .unremovable() .done() );
运行时出现依赖不满足错误:
[ERROR] HealthCheckTest.testHealth » Runtime java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type java.util.List<java.lang.Class<?>> and qualifiers [@io.smallrye.common.annotation.Identifier("test")]
- synthetic injection point
- declared on SYNTHETIC bean [types=[java.lang.Object, com.crv.jms.EventProducer], qualifiers=[@Any, @io.smallrye.common.annotation.Identifier("test")], target=n/a]
The following beans match by type, but none has matching qualifiers:- PRODUCER METHOD bean [types=[java.util.List, java.lang.Object], qualifiers=[@Any, @ConfigProperty], target=java.util.List producesListConfigProperty(jakarta.enterprise.inject.spi.InjectionPoint ip), declaringBean=io.smallrye.config.inject.ConfigProducer]
问题分析
核心问题是泛型类型的注册与注入点不匹配。Quarkus CDI容器对泛型依赖的解析会严格校验完整的参数化类型信息:
- 创建合成Bean时,仅通过
configure(List.class)指定了原始类型,虽然调用了addType()添加泛型类型,但该类型未被作为Bean的核心匹配类型; - 注入点要求的是
List<Class<?>>,但容器只识别到原始类型List的Bean,且该Bean的Qualifier不匹配; - 需确保Bean注册的类型与注入点的类型元数据完全一致,包括泛型参数的细节。
修复方案
1. 正确注册泛型类型的合成Bean
直接使用泛型类型配置合成Bean,同时保留原始类型作为备选,确保容器能识别完整的参数化类型:
// 构造List<Class<?>>的完整类型元数据 Type listOfClassType = com.crv.jms.Util.createType(); syntheticBeanProducer.produce( SyntheticBeanBuildItem.configure(listOfClassType) // 用泛型类型作为配置入口 .scope(Singleton.class) .addType(List.class) // 添加原始类型,兼容更多场景 .unremovable() .addQualifier().annotation(Identifier.class).addValue("value", name).done() .createWith(recorder.createSupportedEventTypesList(supportedEventTypes)) .done() );
2. 确保注入点与Bean的类型、Qualifier完全匹配
- 确认
com.crv.jms.Util.createType()在两处生成的是完全相同的List<Class<?>>类型元数据; - 检查
Identifier注解的value值(即name变量)在创建Bean和注入点时完全一致,无拼写、大小写差异。
3. 冗余配置清理
移除重复的unremovable()调用(原代码中出现了两次),避免不必要的配置冲突。
内容的提问来源于stack exchange,提问作者jelmew

