Spring @Async with CompletableFuture

怎甘沉沦 提交于 2019-12-17 22:35:37

问题


I have a doubt about this code:

@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;
}

The question is: does doFoo return fooFuture only after longOp has finished (either correctly or exceptionally) and is therefore returning already completed futures or is Spring doing some magic and returning before executing the body? If the code is blocking on longOp(), how would you express that the computation is being fed to an executor?

Perhaps this? Any other way?

@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:


Spring actually does all of the work behind the covers so you don't have to create the CompletableFuture yourself. Basically, adding the @Async annotation is as if you called your original method (without the annotation) like:

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

As for your second question, in order to feed it to an executor, you can specify the exectutor bean name in the value of the @Async annotation, like so:

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

The above would basically be the following as if you called your original method, like:

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

And all of your exceptionally logic you would do with the returned CompletableFuture from that method.



来源:https://stackoverflow.com/questions/47351435/spring-async-with-completablefuture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!