Spring @Async 与 CompletableFuture

Spring @Async with CompletableFuture

我对这段代码有疑问:

@Async
public CompletableFuture<String> doFoo() {
    CompletableFuture<String> fooFuture = new CompletableFuture<>();  

    try {
        String fooResult = longOp();
        fooFuture.complete(fooResult);
    } catch (Exception e) {
        fooFuture.completeExceptionally(e);
    }

    return fooFuture;
}

问题是:doFoo return fooFuture 仅在 longOp 完成后(正确或异常),因此 returning 已经完成的期货或 Spring 做一些魔术和 returning 在执行 body 之前?如果代码在 longOp() 上阻塞,您将如何表示计算被提供给执行程序?

也许是这个?还有其他方法吗?

@Async
public CompletableFuture<String> doFoo() {

    CompletableFuture<String> completableFuture = new CompletableFuture<>();
    CompletableFuture.runAsync(() -> {
        try {
            String fooResult = longOp();
            completableFuture.complete(fooResult);
        } catch (Exception e) {
            completableFuture.completeExceptionally(e);
        }
    });
    return completableFuture;
}

Spring 实际上完成了所有幕后工作,因此您不必自己创建 CompletableFuture。 基本上,添加 @Async 注释是 ,就好像 您调用原始方法(没有注释)一样:

CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo());

关于你的第二个问题,为了将它提供给执行程序,你可以在 @Async 注释的 value 中指定执行程序 bean 名称,如下所示:

    @Async("myExecutor")
    public CompletableFuture<User> findUser(String usernameString) throws InterruptedException {
        User fooResult = longOp(usernameString);
        return CompletableFuture.completedFuture(fooResult);
    }

上面基本上是下面的好像你调用了你原来的方法,比如:

CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo(), myExecutor);

以及您将使用该方法返回的 CompletableFuture 执行的所有 exceptionally 逻辑。