I want to Use @Async
annotation on method for running it asynchronously. I have defined my ThreadExecutor
as follows:
@Bean("threadPoolTaskExecutor")
public TaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(200);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(30);
executor.setThreadNamePrefix("async-");
executor.setQueueCapacity(50);
executor.initialize();
return executor;
}
My question is, is it mandatory to use CompletableFuture
as return type for the method using @Async
annotation? Will it work if my third party REST calls returns different/Custom types? for e.g.
@Async("threadPoolTaskExecutor")
public ResponseDTO getCapa(final List<String> vins) {
for (String vin : vins) {
CapabilityDTO capabilityDTO = new CapabilityDTO();
// call third party
Optional<ResponseDTO> response=thirdPartyClient.getInfo();
..........
return response.get();
}
}
or I must use CompletableFuture<ResponseDTO>
??
As per the Spring Async javadoc:
the return type is constrained to either
void
orFuture
. In the latter case, you may declare the more specificListenableFuture
orCompletableFuture
types which allow for richer interaction with the asynchronous task and for immediate composition with further processing steps.
In practice, I believe that if you declare another type, the caller will receive a null
value since no value will be available at the moment of the call and it has to return immediately, so the caller won’t be able to retrieve the result.
If you want to be able to access the result, you must thus return a Future
containing it. Easiest is probably to just use
return CompletableFuture.completedFuture(response.get())
Spring Async will then take care of forwarding your result to the caller when your method returns.