Quarkus中如何正确注入同一接口的所有Bean实例列表?
问题原因
注入列表为空的核心原因是 CDI的Bean类型匹配默认会校验泛型参数:你注入的目标类型是原始类型IssueChangeChainLink,但现有实现类全部实现的是绑定了具体泛型参数的IssueChangeChainLink<AddJiraIssueDTO>、IssueChangeChainLink<IssueAddSprintDTO>,这些Bean的注册类型里不包含无泛型参数的原始IssueChangeChainLink,因此无法被匹配到。
另外类中定义的包私有setLinks方法也可能干扰CDI的注入解析,产生不必要的歧义。
修改步骤
针对责任链的使用场景,直接做以下两处修改即可:
- 给泛型接口
IssueChangeChainLink添加Quarkus Arc提供的@NoTypeCheck注解,标记该接口的实现类在注入匹配时跳过泛型参数校验:
import io.quarkus.arc.NoTypeCheck; @NoTypeCheck public interface IssueChangeChainLink<T> { T getChangeItem(JiraChangeDTO change); void processChangeItem(T changeItem); }
- 修改
IssueChangeChain类:删除多余的包私有setLinks方法,将注入的列表泛型改为通配符形式,避免原始类型的泛型警告和类型校验问题:
@ApplicationScoped public class IssueChangeChain { private static final Logger logger = LoggerFactory.getLogger(IssueChangeChain.class); @Inject @All List<IssueChangeChainLink<?>> links; public void processIssueChange(JiraChangeDTO change) { logger.info("Try to process " + change + " through " + links); if(change == null) return; links.forEach(link ->{ var changeItem = link.getChangeItem(change); if (changeItem != null) { link.processChangeItem(changeItem); } }); } }
修改完成后重启应用,所有IssueChangeChainLink的实现类都会被自动注入到links列表中。
可选扩展(控制责任链执行顺序)
如果需要指定各个链节点的执行顺序,不需要额外修改注入逻辑,只需给每个实现类添加@Priority注解即可,数值越小执行优先级越高:
@ApplicationScoped @Priority(10) // 第一个执行 public class IssueCreationChainLink implements IssueChangeChainLink<AddJiraIssueDTO> { // 原有逻辑不变 } @ApplicationScoped @Priority(20) // 第二个执行 public class SprintChangeChainLink implements IssueChangeChainLink<IssueAddSprintDTO> { // 原有逻辑不变 }
如果需要自动按优先级排序,把注入逻辑改成Instance方式在初始化方法里处理即可:
@ApplicationScoped public class IssueChangeChain { private static final Logger logger = LoggerFactory.getLogger(IssueChangeChain.class); @Inject @All Instance<IssueChangeChainLink<?>> linkInstances; List<IssueChangeChainLink<?>> links; @PostConstruct void init() { links = linkInstances.stream() .sorted(AnnotationInstance.priorityComparator()) .toList(); } // processIssueChange方法逻辑不变 }
注:Quarkus 2.10.0.Final内置的Arc容器原生支持
@All注解注入同类型所有Bean,不需要引入额外依赖。
内容的提问来源于stack exchange,提问作者Gubber
相关产品推荐
相关产品推荐

