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

Java控制器如何获取异步Service中异步方法返回的数据?

Java @Async异步方法获取返回值解决方案

问题根因

当方法被@Async注解修饰后,Spring会通过代理机制异步执行该方法逻辑,调用方触发方法后会立刻返回,不会等待逻辑执行完成。你当前的写法存在两个核心问题:

  1. 直接通过类名静态调用MG.messageGetter,没有使用Spring托管的Bean实例,@Async注解根本不会生效
  2. 异步方法返回值定义为普通String类型,调用方无法接收异步执行后的返回结果,拿到的值永远为null

修正步骤

第一步:开启异步支持 + 修正Service定义

首先要在项目启动类或者异步配置类上添加@EnableAsync注解,开启Spring异步能力,再修正MG类的写法:

@Service
public class MG {
    @Async
    public CompletableFuture<String> messageGetter(Integer z) {
        // 此处可替换为实际业务逻辑
        return CompletableFuture.completedFuture("HELLOFRIEND");
    }
}

第二步:修正Controller调用逻辑

注入MG的Spring托管实例,需要同步拿到返回值的场景可通过CompletableFuture的get()方法阻塞等待异步结果返回:

@RestController
public class XyzController {
    // 注入Spring托管的MG实例,禁止直接静态调用类方法
    @Autowired
    private MG mg;

    @PostMapping("/xyz")
    void getThatMessageAndEmail(@RequestBody Integer z) throws Exception {
        CompletableFuture<String> futureResult = mg.messageGetter(z);
        // 阻塞等待异步执行完成,获取返回值
        String messageToCatch = futureResult.get();
        System.out.println(functionToConcat(z, messageToCatch));
    }

    // 你的字符串拼接方法自行实现即可
    private String functionToConcat(Integer z, String msg) {
        return z + msg;
    }
}

如果不需要阻塞Controller主线程,可使用回调方式非阻塞处理结果:

@PostMapping("/xyz")
void getThatMessageAndEmail(@RequestBody Integer z) {
    mg.messageGetter(z).thenAccept(messageToCatch -> {
        System.out.println(functionToConcat(z, messageToCatch));
    });
}

注意事项

  • 异步方法必须是public修饰,不能是static、private,否则Spring代理会失效
  • 异步方法不要和调用方写在同一个类中,否则会绕过代理导致@Async不生效
  • get()方法可以设置超时时间,避免异步逻辑故障导致主线程长时间阻塞,写法为futureResult.get(3, TimeUnit.SECONDS)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:45:06