与CompletableFuture的Spring @Async

时间:2017-11-17 13:10:33

标签: 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;
}

问题是: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;
}

1 个答案:

答案 0 :(得分:17)

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

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

至于你的第二个问题,为了将它提供给执行者,你可以在@Async注释的value中指定exectutor 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);

您使用该方法返回的exceptionally所做的所有CompletableFuture逻辑。