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

Quarkus生产者方法无日志、无法调试及Bean注入异常问题咨询

问题分析与解答

问题现象

  1. DocumentCreatorFactory中的生产者方法getSomeBeans无控制台日志输出,也无法调试
  2. SomeBeanService中直接注入的Instance<SomeBean>找不到任何Bean,但通过@Any修饰的Instance配合限定符筛选后能找到对应Bean

相关代码片段

生产者类

@ApplicationScoped
@JBossLog
public class DocumentCreatorFactory {
   @Produces
   @ApplicationScoped
   public List<SomeBean> getSomeBeans(@Any Instance<SomeBean> someBeans) {
      log.infof("######### Producer started: %d #########", documentCreators.stream().count());
      return someBeans.select(
          TagContext.Literal.of(Tag.CORE, Tag.CH)
      ).stream().toList();
   }
}

限定符注解定义

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface TagContext {

   Tag[] value() default {Tag.CORE};

   final class Literal extends AnnotationLiteral<TagContext> implements TagContext {

      private final Tag[] value;

      public static Literal of(Tag... value) {
         return new Literal(value);
      }

      private Literal(Tag... value) {
         this.value = value;
      }

      @Override
      public Tag[] value() {
         return value;
      }
   }
}

Bean实现类

@TagContext({Tag.CORE, Tag.CH})
@ApplicationScoped
@JBossLog
public class TagCoreAndChService implements SomeBean {
   @Override
   public void create() {
      log.infof("Core And Ch Some Bean Create");
   }
}

@TagContext
@ApplicationScoped
@JBossLog
public class TagCoreService implements SomeBean {
   @Override
   public void create() {
      log.infof("Core And Ch Some Bean Create");
   }
}

Bean使用类

@ApplicationScoped
@JBossLog
public class SomeBeanService {
   @Inject Instance<SomeBean> someBeans;
   @Inject @Any Instance<SomeBean> allSomeBeans;

   public void someProcessing(String inParam) {
      // 检查计数时未找到任何Bean
      log.infof("Num of beans: %d", someBeans.stream().count());
      Instance<DocumentCreator> core = allSomeBeans.select(
          Literal.of(Tag.CORE, Tag.CH)
      );
      // 在此处操作后能找到部分Bean
      log.infof("Num of beans AFTER: %d", core.stream().count());
   }
}

原因分析

1. 生产者方法未执行的原因

  • CDI生产者方法仅在被生产的类型被注入时才会触发执行:当前代码中没有任何地方注入List<SomeBean>,所以getSomeBeans方法根本不会被调用,自然看不到日志也无法调试。
  • 代码存在变量名错误:方法内使用了未定义的documentCreators变量,实际参数名是someBeans,就算方法执行也会抛出空指针异常。

2. 直接注入的Instance<SomeBean>找不到Bean的原因

  • 直接注入Instance<SomeBean>时,CDI会默认查找不带任何限定符的SomeBean实例,但你的两个SomeBean实现类都带有@TagContext限定符,不符合无限定符的查找条件,因此找不到Bean。
  • @Any修饰的Instance会匹配所有SomeBean类型的Bean(无论是否带限定符),之后通过select(TagContext.Literal.of(Tag.CORE, Tag.CH))筛选,能匹配到TagCoreAndChService,所以能找到对应Bean。

解决建议

  1. 触发生产者方法执行:在需要使用筛选后Bean列表的类中注入List<SomeBean>,比如在SomeBeanService中添加:

    @Inject List<SomeBean> filteredSomeBeans;
    

    同时修正生产者方法中的变量名错误,将documentCreators改为someBeans。

  2. 让直接注入的Instance<SomeBean>找到目标Bean:给注入点添加对应限定符,比如:

    // 匹配所有带@TagContext的Bean
    @Inject @TagContext Instance<SomeBean> someBeans;
    

    或者匹配特定Tag组合:

    @Inject @TagContext({Tag.CORE, Tag.CH}) Instance<SomeBean> someBeans;
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:04:58