Spring Boot Async
Tags: springboot, beginners, programming
Published: 2022-11-15 00:11:09

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.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1667878692424/q0D7-UszS.png align="left")


## 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.


## References

- [Annotation Support for Scheduling and Asynchronous Execution](https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling-annotation-support)

- [The @Async annotation](https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling-annotation-support-async)