如何不使用注解让Quarkus CDI发现Bean并实现依赖注入
Quarkus无需修改业务类实现Bean注入的两种方案
你遇到的UnsatisfiedResolutionException是因为Quarkus的CDI容器默认没有将无作用域注解的RosterService识别为可注入的Bean,以下是两种不需要在RosterService类上添加注解的实现方案:
方案1:Jandex索引+XML声明Bean作用域
该方案通过配置索引和XML文件完成Bean声明,完全不侵入业务代码:
- 第一步:添加Jandex索引插件,将项目类加入Quarkus的扫描范围
Maven配置(pom.xml):
Gradle配置(build.gradle):<build> <plugins> <plugin> <groupId>io.smallrye</groupId> <artifactId>jandex-maven-plugin</artifactId> <version>3.1.5</version> <executions> <execution> <id>generate-jandex-index</id> <goals> <goal>jandex</goal> </goals> </execution> </executions> </plugin> </plugins> </build>plugins { id 'org.kordamp.gradle.jandex' version '1.2.0' } - 第二步:在
src/main/resources/META-INF/beans.xml中声明RosterService的作用域
如果使用的是旧版Quarkus(基于Java EE),将所有<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd" version="4.0" bean-discovery-mode="annotated"> <managed-bean> <class>替换为RosterService的全限定类名</class> <scope>jakarta.enterprise.context.ApplicationScoped</scope> </managed-bean> </beans>jakarta包名替换为javax即可
方案2:@BuildStep手动注册Bean
该方案适合注册第三方依赖中的类作为Bean,步骤如下:
- 第一步:引入Arc部署依赖(pom.xml)
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-arc-deployment</artifactId> <scope>provided</scope> </dependency> - 第二步:创建Bean注册处理器类
import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem; import io.quarkus.builder.BuildContext; import io.quarkus.builder.BuildStep; import jakarta.enterprise.context.ApplicationScoped; public class CustomBeanProcessor { @BuildStep void registerRosterServiceBean(BeanRegistrationPhaseBuildItem phase, BuildContext context) { phase.getBeanConfigurator() .addBeanClass(RosterService.class) .scope(ApplicationScoped.class) .done(); } } - 第三步:注册处理器,在
src/main/resources/META-INF/services/io.quarkus.builder.BuildStepProvider文件中添加处理器的全限定类名即可。
补充极简方案:@Producer生产Bean
如果不需要自定义扩展,最简单的无侵入方案是在任意已被Quarkus识别的Bean中添加生产方法:
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; @ApplicationScoped public class CustomBeanProducer { @Produces @ApplicationScoped public RosterService produceRosterService() { // 可以在这里自定义RosterService的初始化逻辑 return new RosterService(); } }
内容的提问来源于stack exchange,提问作者BigONotation
相关产品推荐
相关产品推荐

