How to Use Async Method in Spring Boot for Background Tasks
In Spring Boot, you use
@Async on a method to run it asynchronously. Enable async support with @EnableAsync on a configuration class, and the method should return a CompletableFuture or void. This lets the method run in the background without blocking the caller.Syntax
To use async methods in Spring Boot, you annotate a method with @Async. The method can return void, CompletableFuture<T>, or other Future types. You must enable async processing by adding @EnableAsync on a configuration or main class.
@EnableAsync: Enables Spring's async support.@Async: Marks a method to run asynchronously.- Return type
CompletableFuture<T>: Allows handling the async result.
java
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Service; import java.util.concurrent.CompletableFuture; @EnableAsync @Service public class AsyncService { @Async public CompletableFuture<String> asyncMethod() { // Your async code here return CompletableFuture.completedFuture("Done"); } }
Example
This example shows a Spring Boot service with an async method that simulates a delay and returns a message. The main application calls this method and continues without waiting.
java
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Service; import org.springframework.scheduling.annotation.Async; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @SpringBootApplication @EnableAsync public class AsyncExampleApplication { public static void main(String[] args) throws Exception { var context = SpringApplication.run(AsyncExampleApplication.class, args); AsyncService service = context.getBean(AsyncService.class); System.out.println("Calling async method..."); CompletableFuture<String> future = service.asyncMethod(); System.out.println("Doing other work while async runs..."); // Wait for async result System.out.println("Async result: " + future.get()); context.close(); } @Service public static class AsyncService { @Async public CompletableFuture<String> asyncMethod() { try { TimeUnit.SECONDS.sleep(2); // Simulate delay } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return CompletableFuture.completedFuture("Async Task Completed"); } } }
Output
Calling async method...
Doing other work while async runs...
Async result: Async Task Completed
Common Pitfalls
Common mistakes when using async methods in Spring Boot include:
- Not adding
@EnableAsyncto enable async support, so@Asynchas no effect. - Calling async methods from within the same class directly, which bypasses Spring's proxy and runs synchronously.
- Using return types other than
void,Future, orCompletableFuturewithout proper handling. - Not handling exceptions inside async methods, which can be lost silently.
Example of wrong usage:
java
import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class WrongAsyncService { @Async public void asyncMethod() { System.out.println("Running async task"); } public void callAsync() { // Wrong: calling async method directly in same class asyncMethod(); // This runs synchronously } }
Quick Reference
| Annotation/Concept | Purpose |
|---|---|
| @EnableAsync | Enables Spring's async method execution support |
| @Async | Marks a method to run asynchronously |
| CompletableFuture | Return type to handle async results |
| Calling async methods | Must be called from another bean or via Spring proxy |
| Exception handling | Handle exceptions inside async methods to avoid silent failures |
Key Takeaways
Add @EnableAsync to your Spring Boot application to enable async support.
Annotate methods with @Async to run them asynchronously in a separate thread.
Use CompletableFuture as the return type to get async results.
Do not call @Async methods from the same class directly; call them via Spring-managed beans.
Handle exceptions inside async methods to avoid losing errors silently.