与CompletableFuture的Spring @Async

Edd*_*ddy 15 spring completable-future

我对这段代码有疑问:

@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;
}
Run Code Online (Sandbox Code Playgroud)

问题是:doFoo仅在longOp完成后(正确或异常)返回fooFuture,因此返回已经完成的期货,或者Spring在执行主体之前做了一些魔法并返回?如果代码在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;
}
Run Code Online (Sandbox Code Playgroud)

Dov*_*vmo 23

Spring实际上完成了封面背后的所有工作,因此您无需CompletableFuture自己创建.基本上,添加@Async注释就好像你调用原始方法(没有注释),如:

CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo());
Run Code Online (Sandbox Code Playgroud)

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

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

上面的内容基本上就像你调用原始方法一样,如:

CompletableFuture<User> future = CompletableFuture.runAsync(() -> doFoo(), myExecutor);
Run Code Online (Sandbox Code Playgroud)

并且exceptionally您将使用该CompletableFuture方法返回的所有逻辑.