You need to use spring's AsyncResult class to wrap your result and then use its method .completable() to return CompletableFuture object.
When merging future object use CompletableFuture.thenCompose() and CompletableFuture.thenApply() method to merge the data like this:
CompletableFuture<Integer> result = futureData1.thenCompose(fd1Value -> futureData2.thenApply(fd2Value -> merge(fd1Value, fd2Value)));
Here is a basic example:
Annotate Spring boot main class with @EnableAsync annotation
@SpringBootApplication @EnableAsync public class StackOverflowApplication { public static void main(String[] args) { SpringApplication.run(StackOverflowApplication.class, args); } }
Create a sample service which will return CompletableFuture
Aservice.java
@Service public class Aservice { @Async public CompletableFuture<Integer> getData() throws InterruptedException { Thread.sleep(3000); // sleep for 3 sec return new AsyncResult<Integer>(2).completable(); // wrap integer 2 } }
Bservice.java
@Service public class Bservice { @Async public CompletableFuture<Integer> getData() throws InterruptedException { Thread.sleep(2000); // sleep for 2 sec return new AsyncResult<Integer>(1).completable(); // wrap integer 1 } }
Create another service which will merge other two service data
ResultService.java
@Service public class ResultService { @Autowired private Aservice aservice; @Autowired private Bservice bservice; public CompletableFuture<Integer> mergeResult() throws InterruptedException, ExecutionException { CompletableFuture<Integer> futureData1 = aservice.getData(); CompletableFuture<Integer> futureData2 = bservice.getData(); // Merge futures from Aservice and Bservice return futureData1.thenCompose( fd1Value -> futureData2.thenApply(fd2Value -> fd1Value + fd2Value)); } }
Create a sample controller for testing
ResultController.java
@RestController public class ResultController { @Autowired private ResultService resultService; @GetMapping("/result") CompletableFuture<Integer> getResult() throws InterruptedException, ExecutionException { return resultService.mergeResult(); } }