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
相关产品推荐
相关产品推荐

