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

Byte Buddy使用.andThen时返回值丢失,如何保留原方法返回值?

问题分析与解决方案

你的问题出在andThen(MethodCall.run(new CloseConnection()))的用法上:当链式调用andThen时,Byte Buddy会将整个拦截逻辑的返回值设置为最后一个操作的结果。而MethodCall.run(new CloseConnection())执行的是Runnable的run()方法(返回void),这就导致原proxyClient方法的返回值被覆盖丢弃了。

要在保留原方法返回值的同时,在方法执行后添加额外逻辑,有两种更合适的方式:

方式一:使用Byte Buddy Advice(推荐)

Advice是Byte Buddy中处理方法拦截的轻量且灵活的方式,通过注解可以轻松在方法执行前后插入逻辑,且自动保留原返回值:

T proxyClient = JAXRSClientFactory.fromClient(client, classType, true);
this.configureHttpConduit(conduit, invocationTimeout);

Class<?> buddy = new ByteBuddy()
    .subclass(classType)
    .method(ElementMatchers.isAnnotatedWith(Path.class))
    .intercept(MethodDelegation.to(proxyClient).andThen(Advice.to(CloseConnectionAdvice.class)))
    .make()
    .load(this.getClass().getClassLoader(), Default.INJECTION)
    .getLoaded();

return (T) buddy.newInstance();

// 定义Advice类
static class CloseConnectionAdvice {
    @Advice.OnMethodExit
    static void afterMethod() {
        System.out.println("close connection called");
    }
}

这里的@Advice.OnMethodExit注解会确保代码在原方法执行完成后运行,无论原方法是否有返回值,都不会影响其返回结果。

方式二:调整MethodDelegation的链式调用

如果你想继续使用MethodDelegation和andThen,需要确保最后一个操作返回原方法的返回值。可以通过Return.of(...)来显式返回原返回值:

T proxyClient = JAXRSClientFactory.fromClient(client, classType, true);
this.configureHttpConduit(conduit, invocationTimeout);

Class<?> buddy = new ByteBuddy()
    .subclass(classType)
    .method(ElementMatchers.isAnnotatedWith(Path.class))
    .intercept(MethodDelegation.to(proxyClient)
        .andThen(MethodCall.run(new CloseConnection()))
        .andThen(Return.ofValue(ArgumentStack.lastValue())))
    .make()
    .load(this.getClass().getClassLoader(), Default.INJECTION)
    .getLoaded();

return (T) buddy.newInstance();

static class CloseConnection implements Runnable {
    @Override
    public void run() {
        System.out.println("close connection called");
    }
}

ArgumentStack.lastValue()会获取原方法执行后的返回值,再通过Return.ofValue将其作为整个拦截逻辑的返回值,这样就不会丢失原返回值了。

额外说明

相比第二种方式,Advice的写法更清晰,性能也更优(因为它是直接修改字节码,而非通过委托链),更推荐在这种场景下使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:48:01