There is no “_vs._” between the two – these are complementary technologies:
* `CompletableFuture` provides a convenient way to chain different stages of asynchronous computation – with more flexibility than Spring's `ListenableFuture`;
* `@Async` provides convenient management of your background tasks and threads, with standard Spring configuration for your executor(s).
But both can be combined ([since Spring 4.2][1]). Suppose you want to turn the following method into a background task returning a `CompletableFuture`:
public String compute() {
// do something slow
return "my result";
}
What you have to do:
* if not already done: configure your application with `@EnableAsync` and an `Executor` bean
* annotate the method with `@Async`
* wrap its result into `CompletableFuture.completedFuture()`
<!-- list followed by code breaks rendering -->
@Async
public CompletableFuture<String> computeAsync() {
// do something slow - no change to this part
// note: no need to wrap your code in a lambda/method reference,
// no need to bother about executor handling
return CompletableFuture.completedFuture("my result");
}
As you notice, you don't have to bother about submitting the background task to an executor: Spring takes care of that for you. You only have to wrap the result into into a completed `CompletableFuture` so that the signature matches what the caller expects.
In fact, this is equivalent to:
@Autowire
private Executor executor;
public CompletableFuture<String> computeAsync() {
return CompletableFuture.supplyAsync(() -> {
// do something slow
return "my result";
}, executor);
}
but it removes the need to:
* inject the executor
* deal with the executor in a `supplyAsync()` call
* wrap the logic in a lambda (or extract it to a separate method)
[1]:
[To see links please register here]