Quarkus 2.9.2.Final中@GrpcClient注入gRPC服务失败引发空指针异常的问题求助
你遇到的核心问题是你的PlatformDataClientImpl类没有被Quarkus的CDI容器托管,导致@GrpcClient注解完全没生效,注入的baz实例始终为null。手动实例化能正常工作,是因为你绕开了CDI依赖注入机制,直接创建了对象和通道。
最关键的修复步骤:给客户端类添加CDI作用域注解
Quarkus的CDI容器只会管理带有特定注解的类(比如@ApplicationScoped、@RequestScoped等),如果你的类没有这些注解,容器不会处理其中的@GrpcClient或@Inject注入逻辑。
修改你的PlatformDataClientImpl类,添加@ApplicationScoped注解:
import jakarta.enterprise.context.ApplicationScoped; import io.quarkus.grpc.runtime.annotations.GrpcClient; @ApplicationScoped // 必须添加这个注解让CDI托管该类 class PlatformDataClientImpl { @GrpcClient("baz") GrpcPlatform baz; // 你的getAllPlatforms方法保持不变 public Uni<List<Platform>> getAllPlatforms() { return baz .getAllPlatforms(PlatformProto.GetAllRequest.newBuilder().build()) .onItem() .transform(platformResponse -> platformResponse .getPlatformList() .stream() .map(this::transformPlatform) .collect(Collectors.toList()) ); } }
额外的检查项(确保万无一失)
确认注入的Stub类型正确:
检查target/generated-sources/grpc下的生成类,确保GrpcPlatform是Quarkus适配的Mutiny版本Stub(你手动实例化能工作,说明类型本身没问题,但可以再确认下生成逻辑是否正常)。验证gRPC客户端配置:
在application.properties中确认已经配置了baz客户端的连接信息:quarkus.grpc.clients.baz.host=你的服务端地址 quarkus.grpc.clients.baz.port=你的服务端端口你手动实例化能工作,说明配置大概率没问题,但还是建议核对一遍。
确保正确注入客户端实例:
当你在其他类(比如ExampleResource)中使用PlatformDataClientImpl时,也要通过CDI注入,而不是手动new:@Path("/example") public class ExampleResource { @Inject PlatformDataClientImpl dataClient; // 用CDI注入,不要手动new @GET @Path("/test") public Uni<List<Platform>> gTest() { return dataClient.getAllPlatforms(); } }
为什么手动实例化能工作?
手动创建Stub和通道时,你直接通过代码构建了完整的客户端实例,不需要依赖CDI容器的注入逻辑,所以能正常调用。但依赖注入的方式必须让CDI容器接管类的生命周期,它才会帮你完成@GrpcClient的注入工作。
内容的提问来源于stack exchange,提问作者Ernest Kahnwald

