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

Quarkus Rest-Client-Reactive:如何解包RestClientCdiWrapper获取方法参数信息?

解决Quarkus RestClient Reactive拦截器无法获取原接口方法元数据的问题

方法一:通过CDI获取原始REST Client接口的方法元数据

由于Reactive版本的RestClient是CDI动态生成的代理包装类,直接从InvocationContext拿到的方法是代理类的方法,所以需要通过原始接口类型匹配获取真实方法:

@Inject
BeanManager beanManager;

public void intercept(InvocationContext context) throws Exception {
    // 提取被代理的原始RestClient接口
    Class<?> originalInterface = context.getTarget().getClass().getInterfaces()[0];
    // 根据方法名和参数类型匹配原始方法
    Method originalMethod = originalInterface.getMethod(
        context.getMethod().getName(),
        context.getMethod().getParameterTypes()
    );
    
    // 现在可以正常获取参数注解和真实参数名
    Parameter[] originalParams = originalMethod.getParameters();
    for (Parameter param : originalParams) {
        Annotation1 anno = param.getAnnotation(Annotation1.class);
        String realParamName = param.getName(); // 需开启编译参数保留参数名
    }
    
    // 执行原方法逻辑
    context.proceed();
}

关键配置:
编译时必须开启-parameters参数,才能保留参数名(否则还是显示arg0)。在pom.xml中配置Maven编译器:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.11.0</version>
            <configuration>
                <parameters>true</parameters>
            </configuration>
        </plugin>
    </plugins>
</build>

方法二:使用Reactive RestClient专用拦截器机制

Quarkus Reactive RestClient推荐使用JAX-RS标准的ClientRequestFilter或者Quarkus扩展的RestClientRequestFilter,这种方式能直接拿到请求关联的原始方法元数据:

@Provider
public class MyReactiveRequestFilter implements ClientRequestFilter {
    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        // 从请求上下文获取原始方法对象
        Method originalMethod = (Method) requestContext.getProperty("org.jboss.resteasy.reactive.common.core.Method");
        
        if (originalMethod != null) {
            Parameter[] params = originalMethod.getParameters();
            // 处理参数注解和名称
            for (Parameter param : params) {
                Annotation2 anno = param.getAnnotation(Annotation2.class);
                String paramName = param.getName();
            }
        }
    }
}

然后在RestClient接口上注册该拦截器:

@RegisterRestClient(configKey = "someKey")
@RegisterProvider(MyReactiveRequestFilter.class)
public interface MyRestClient {
    @GET
    @Path("/something")
    User getSomething(@Annotation1 @Annotation2 final String someParameter);
}

方法三:解包CDI代理对象(备选方案)

如果需要直接处理代理对象,可通过Quarkus的ArcContainer获取Bean元数据,但本质还是通过原始接口类型匹配方法:

@Inject
ArcContainer arcContainer;

public void intercept(InvocationContext context) throws Exception {
    Class<?> originalInterface = context.getTarget().getClass().getInterfaces()[0];
    Bean<?> restClientBean = arcContainer.beanManager().resolve(
        arcContainer.beanManager().getBeans(originalInterface)
    );
    
    Method originalMethod = restClientBean.getBeanClass().getMethod(
        context.getMethod().getName(),
        context.getMethod().getParameterTypes()
    );
    
    // 后续处理同方法一
    context.proceed();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:17:27