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

Quarkus是否有类似@ConditionalOnBean的注解或方法?扩展开发咨询

Quarkus扩展:根据BeanA存在性注册BeanB的解决方案

核心思路

在Quarkus构建阶段的BuildStep中,通过CombinedIndexBuildItem获取全应用的类元数据索引,检查用户自定义的BeanA是否存在且被标记为合法CDI Bean,以此决定是否注册BeanB。

你之前代码的问题

用getKnownUsers()是找哪些类用到了BeanA(比如把BeanA当字段、参数的类),不是判断BeanA本身是不是被定义成了CDI Bean,所以逻辑不对。

正确实现代码

import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.AdditionalBeanBuildItem;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;

@BuildStep
void registerBeanProducers(CombinedIndexBuildItem combinedIndex,
                           BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
    // 拿到BeanA的类名对应的DotName
    DotName beanADotName = DotName.createSimple(BeanA.class.getName());
    ClassInfo beanAClassInfo = combinedIndex.getIndex().getClassByName(beanADotName);

    if (beanAClassInfo != null) {
        // 检查这个类是否带CDI作用域注解(比如@ApplicationScoped、@Singleton)
        boolean isCdiBean = beanAClassInfo.annotations().stream()
                .anyMatch(anno -> {
                    DotName annoName = anno.name();
                    // 匹配Jakarta EE的CDI作用域
                    return annoName.startsWith("jakarta.enterprise.context.")
                            // 兼容旧版Java EE注解
                            || annoName.startsWith("javax.enterprise.context.")
                            // 如果要支持Spring风格的Bean,加这个判断
                            || annoName.equals(DotName.createSimple("org.springframework.stereotype.Component"));
                });

        if (isCdiBean) {
            // 注册不可移除的BeanB
            AdditionalBeanBuildItem beanBItem = AdditionalBeanBuildItem.builder()
                    .setUnremovable()
                    .addBeanClass(BeanB.class)
                    .build();
            additionalBeans.produce(beanBItem);
        }
    }
}

更精准的Bean判断(进阶)

如果要严格按照Quarkus的CDI规则判断BeanA是否会被识别为Bean,可以用Arc的BeanProcessor:

import io.quarkus.arc.processor.BeanInfo;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.AdditionalBeanBuildItem;
import io.quarkus.deployment.builditem.BeanProcessorBuildItem;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;

@BuildStep
void registerBeanProducers(CombinedIndexBuildItem combinedIndex,
                           BeanProcessorBuildItem beanProcessorItem,
                           BuildProducer<AdditionalBeanBuildItem> additionalBeans) {
    DotName beanADotName = DotName.createSimple(BeanA.class.getName());
    ClassInfo beanAClassInfo = combinedIndex.getIndex().getClassByName(beanADotName);

    if (beanAClassInfo != null) {
        // 用Arc的BeanProcessor分析类是否为合法Bean
        BeanInfo beanInfo = beanProcessorItem.getBeanProcessor().buildBeanInfo(beanAClassInfo, combinedIndex.getIndex());
        if (beanInfo != null && beanInfo.isBean()) {
            // 注册BeanB
            AdditionalBeanBuildItem beanBItem = AdditionalBeanBuildItem.builder()
                    .setUnremovable()
                    .addBeanClass(BeanB.class)
                    .build();
            additionalBeans.produce(beanBItem);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:01:00