Spring Boot - Async methods
Get some clarity on async methods with this tutorial that demonstrates how to enable them and annotate the related methods.
Join the DZone community and get the full member experience.
Join For FreeThe key steps behind enabling Async methods in Spring are here:
1) Enable async processing in Spring Boot by annotation Spring Boot Application class with @EnableAsync
2) Create a ThreadPoolExecutor
to run async methods in separate threads
3) Annotate the methods that need to be run in separate threads with @Async
annotation
This is explained in the blog post at the Spring site.
I had a look at it and then started applying the changes in the project accordingly. It worked fine and solved the issues that we faced with performance.
In that blog post, usage of Async method was explained by creating a service method, annotated with @Async
annotation, that makes a call to GitHub API.
While reading the post, couple of things that struck me in that blog post:
1) When using Async methods, the return type of method must be CompletableFuture
2) Following are the lines of code that make a call to Async service method
page1
got populated with the return value of the service method after the control has gone beyond Line 1.
The service method is like this:
xxxxxxxxxx
public CompletableFuture<User> findUser(String user) throws InterruptedException {
logger.info("Looking up " + user);
String url = String.format("https://api.github.com/users/%s", user);
User results = restTemplate.getForObject(url, User.class);
// Artificial delay of 1s for demonstration purposes
Thread.sleep(1000L);
return CompletableFuture.completedFuture(results); //IT IS completedFuture
}
The service method does not encapsulate the whole process in the CompletableFuture, rather all the processing is done and then at the end CompletableFuture was created to hold the results. So how is the asynchronous nature is achieved?
I started debugging. Following are my observations.
Whenever any method is annotated with @Async
annotation, Spring automatically creates a proxy object for that class and injects that proxy into other classes that depend on this class. So any call to the async method goes through the proxy.
A class AsyncExecutionInterceptor
intercepts the Async
method calls and creates a CompletableFuture
object and returns it.
Now the question is this. Since this interceptor class is creating CompletableFuture, why should the service method also need to do the same. Can the service method just return the object instead of wrapping it in a CompletableFuture?
The answer is "No", because the interceptor is actually called by proxy that Spring has created. To achieve async nature for methods, usage of CompletableFuture is necessary.
But, we cannot have different return types for actual method and the method present in the proxy. Both must have same return type. That is the reason that even the service method must return value wrapped in a CompletedFuture.
Hope this helps in understanding async methods better.
Opinions expressed by DZone contributors are their own.
Comments