Asynchronous methods using @Async annotation (Spring)

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.

Leave a Reply

Your email address will not be published. Required fields are marked *