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)