How to do @Async operation in spring boot

Using @Async annotation we can create the asynchronous method in spring. If we add @Async annotation on the method then spring Will execute the method in a separate thread in the background thread pool. 

Enabling @Async support in spring boot

To enable asynchronous processing, you need to add @EnableAsync in the spring configuration class. @EnableAsync annotation will look for a method marked with @Async annotation and run them in the background thread pool. 
@Configuration
@EnableAsync
public class AsyncConfig {
    ...
}
 

@Async has two rules

  1. It must be applied to the public method only.
  2. Self-invocation is not allowed. That means calling the async method from the same class is not work.
The reason for the above rule is very simple The method needs to be public so that can be provided and self-innovation doesn't work because it passes the proxy and call the method directly.

The method with void return type

The method with a void return type works like a runnable thread.

@Async
public void asyncMethod(){
    Sysout("Executing asycn :"+ Thread.currentThread.getName());
}

The method with Return type

We can also add return type by wrapping the return value into Future or Completablefuture.

@Async
public Future<String> asyncMethod(){
    Sysout("Executing asycn :"+ Thread.currentThread.getName());
    return new AsyncResult<String>(Thread.currentThread.getName());
}
@Async
public CompletableFuture<String> asyncMethod(){
Sysout("Executing asycn :"+ Thread.currentThread.getName());     return
CompletableFuture.completedFuture(Thread.currentThread.getName()); }

The Executor:

By default spring usage SimpleAsyncTaskExecutor to run the method asynchronously. But we can override the default at two levels: the application level and the method level.

Method level executor

below we are configuring a custom thread pool executor using ThreadPoolTaskExecutore() class. in our configuration class, we have created a thread pool bean, so our Async annotation will use this custom thread pool for thread execution.

@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean("asyncExecution")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("JDAsync-");
        executor.initialize();
        return executor;
    }
}

Then we should use this bean name with async 

@Async("asyncExecution")
public Future<String> asyncMethod(){
    Sysout("Executing asycn :"+ Thread.currentThread.getName());
    return new AsyncResult<String>(Thread.currentThread.getName());
}


Application level executor : 

The configuration class should implement the AsyncConfigurer interface. So, it has to implement the getAsyncExecutor() method. Here, we will return the executor for the entire application. This now becomes the default executor to run methods annotated with @Async:

@Configuration
@EnableAsync
public class AsyncConfig implement asyncConfigurer {
    @Overried
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("JDAsync-");
        executor.initialize();
        return executor;
    }
}

Comments

Popular posts from this blog

public static void main(String [] args) - Full Explanation

Coding Problem 3 - Weather Observation Station 7 [HackerRank - SQL]

Date Range Picker In Angular 10