Asynchronous methods using @Async annotation (Spring)
Overview
Let’s imagine that you need to call a time-consuming service method from a controller and its result can be postponed. For example, it can import a huge number of records to a database and you can’t force the client to wait minutes/hours for a response. In such a case, it makes sense to make such a method asynchronous, i.e. a separate thread will be created to process the task, but the controller will immediately return to the user. Spring can easily help to configure asynchronous methods using @Async annotation.
Asynchronous methods implementation
First of all, @EnableAsync annotation has to be added to the configuration or application class. Also, the corresponding configuration can be created to define explicitly how threads will be managed under the hood.
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @Configuration @EnableAsync public class AsyncConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setMaxPoolSize(1); executor.setCorePoolSize(1); executor.setThreadNamePrefix("CUSTOM-"); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (throwable, method, objects) -> { System.out.println(method.getName() + ": " + throwable.getMessage()); }; } }
When the configuration is ready, all we need to do is to add @Async annotation at a service method.
import org.springframework.scheduling.annotation.Async; @Async public void importRecords() { ... }
Finally, when the service method will be executed from a controller, it will be executed asynchronously.