Quarkus v2.15.3.Final中RestClient依赖注入失败问题
问题现象
使用Java 17 + Quarkus v2.15.3.Final开发应用,通过MicroProfile RestClient调用第三方API时,执行quarkus dev启动应用抛出依赖注入异常:
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type com.abc.xyz.zoho.ZohoRestClient and qualifiers [@Default]
- java member: com.abc.xyz.zoho.client.ClientServiceImpl#zohoRestClient
- declared on CLASS bean [types=[com.abc.xyz.zoho.client.ClientServiceImpl, java.lang.Object, com.abc.xyz.zoho.client.ClientService], qualifiers=[@Default, @Any], target=com.abc.xyz.zoho.client.ClientServiceImpl]
注释@Inject仅保留@RestClient后应用可正常启动,但调用API时抛出空指针异常:
ZohoRestClient.generateAccessToken(String, String, String, String)" because "this.zohoRestClient" is null
解决方案
1. 修正RestClient接口注解
移除ZohoRestClient接口上的@ApplicationScoped注解,Quarkus会通过@RegisterRestClient自动生成代理实例:
import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; @RegisterRestClient(baseUri = "https://accounts.zoho.in", configKey = "zoho-api") // 移除@ApplicationScoped public interface ZohoRestClient { @POST @Path("/oauth/v2/token") @Produces(MediaType.APPLICATION_JSON) AccessToken generateAccessToken( @QueryParam("refresh_token") String refreshToken, @QueryParam("client_id") String clientId, @QueryParam("client_secret") String clientSecret, @QueryParam("grant_type") String grantType ); }
2. 保留注入注解组合
在ClientServiceImpl中同时保留@Inject和@RestClient注解,确保CDI正确注入RestClient代理:
// ... 其他代码保持不变 @Inject @RestClient ZohoRestClient zohoRestClient; // ... 其他代码保持不变
3. 完善application.properties配置
添加RestClient对应configKey的基础配置(即使baseUri已在注解中指定,也需配置对应项):
# Zoho API RestClient配置 quarkus.rest-client.zoho-api.url=https://accounts.zoho.in # 可选:配置连接/读取超时 quarkus.rest-client.zoho-api.connect-timeout=5000 quarkus.rest-client.zoho-api.read-timeout=10000
问题原因
- @ApplicationScoped冲突:给RestClient接口添加
@ApplicationScoped会让CDI将其视为普通Bean,破坏Quarkus通过@RegisterRestClient生成代理的逻辑,导致依赖无法解析。 - 注入注解缺失:仅用
@RestClient而不加@Inject时,CDI不会自动注入实例,变量保持null,必须两个注解配合才能触发RestClient代理的注入流程。 - 配置缺失:即使注解中指定了baseUri,也需要在配置文件中配置对应configKey的参数,否则RestClient初始化不完整,可能引发潜在问题。
内容的提问来源于stack exchange,提问作者anonymous

