Today we talk about how to use the annotation @Async of Spring Boot to create method asynchronous in our applications.
Using asynchronous methods allows you to execute tasks that require much time to finish without waiting.
Environment
- Java 11
- Spring Boot 7.0.1
- Maven 3.8.6
Preparing a Method
In this example, we used a method called processDelay that executes a random delay time from 0 to 1500 milliseconds. This method looks like this:
public void processDelay() throws InterruptedException {
      long delay = ThreadLocalRandom.current().nextLong(0, 1500 + 1);
      log.info("processing delay: {}", delay);
      Thread.sleep(delay);
      log.info("delay time processed");
}
The sentence Thread.sleep(delay); is the apply the delay time and the sentence long delay = ThreadLocalRandom.current().nextLong(0, 1500 + 1); get a random long number from 0 to 1500 to indicate the first one the time to wait.
  
  
  Using @Async
With this annotation we can convert a simple method into an asynchronous method, in our example we will convert processDelay method to an asynchronous one, we only need to add the annotation @Async at the top of our method, like this:
@Async
public void processDelay() throws InterruptedException {
    long delay = ThreadLocalRandom.current().nextLong(0, 1500 + 1);
    log.info("processing delay: {}", delay);
    Thread.sleep(delay);
    log.info("delay time processed");
}
Enabling Async
To can use @Async annotation also we need to active the Spring Boot features async, for do that, we need to add the annotation @EnableAsync, this one should be added to a class, I prefer to include it on the main class.
Example:
@SpringBootApplication
@EnableAsync
public class AsyncApplication {
    public static void main(String[] args) {
        SpringApplication.run(AsyncApplication.class, args);
    }
}
Testing
To validate the async method we will use a @RestController to call our method and pass it how many executions to apply the method, this is our controller example:
@RestController
@Slf4j
public class DelayController implements IDelayController {
    private final IAsyncProcessorService asyncProcessorService;
    public DelayController(IAsyncProcessorService asyncProcessorService){
        this.asyncProcessorService = asyncProcessorService;
    }
    @Override
    @GetMapping(value = "delay/{executions}")
    public void processDelayTime(@PathVariable(value = "executions") int executions) throws InterruptedException {
        log.info("Tries: {}", executions);
        for(int i = 0; i < executions; i++) {
            this.asyncProcessorService.processDelay();
        }
    }
}
now, if we run the application and request our controller, we can see how the method is executed as a background task.
022-11-07 22:14:08.958  INFO 35748 --- [nio-8080-exec-2] c.h.l.c.implementations.DelayController  : Tries: 2
2022-11-07 22:14:08.968  INFO 35748 --- [         task-2] c.h.l.s.i.AsyncProcessorService          : processing delay: 957
2022-11-07 22:14:08.968  INFO 35748 --- [         task-1] c.h.l.s.i.AsyncProcessorService          : processing delay: 263
2022-11-07 22:14:09.249  INFO 35748 --- [         task-1] c.h.l.s.i.AsyncProcessorService          : delay time processed
2022-11-07 22:14:09.926  INFO 35748 --- [         task-2] c.h.l.s.i.AsyncProcessorService          : delay time processed
2022-11-07 22:14:15.184  INFO 35748 --- [nio-8080-exec-3] c.h.l.c.implementations.DelayController  : Tries: 2
2022-11-07 22:14:15.185  INFO 35748 --- [         task-3] c.h.l.s.i.AsyncProcessorService          : processing delay: 403
2022-11-07 22:14:15.185  INFO 35748 --- [         task-4] c.h.l.s.i.AsyncProcessorService          : processing delay: 736
2022-11-07 22:14:15.591  INFO 35748 --- [         task-3] c.h.l.s.i.AsyncProcessorService          : delay time processed
2022-11-07 22:14:15.924  INFO 35748 --- [         task-4] c.h.l.s.i.AsyncProcessorService          : delay time processed
The response is very fast, indicating that the controller is not waiting for the delay, other evidence that the method is executing asynchronously.
Conclusion
In this post, we can see how to use the Spring Boot @Async annotation to execute methods in background tasks without that we need to wait until the execution finishes.
 
 
              

 
    
Top comments (0)