How to Use @Async Annotation in Spring Boot for Async Processing
In Spring Boot, use the
@Async annotation on a method to run it asynchronously in a separate thread. Enable async support by adding @EnableAsync on a configuration class or the main application class.Syntax
The @Async annotation marks a method to run asynchronously. You must also enable async processing with @EnableAsync on a configuration or main class. The annotated method should return void, CompletableFuture, or other Future types.
@EnableAsync: Enables Spring's async support.@Async: Marks a method to run in a separate thread.- Return types:
void,Future,CompletableFuturefor async results.
java
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Service; import java.util.concurrent.CompletableFuture; @SpringBootApplication @EnableAsync public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } } @Service public class AsyncService { @Async public CompletableFuture<String> asyncMethod() { // async logic here return CompletableFuture.completedFuture("Done"); } }
Example
This example shows a Spring Boot app with an async method that runs in the background and returns a result. The main thread continues without waiting.
java
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Service; import java.util.concurrent.CompletableFuture; @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("Main thread continues..."); // Wait for async result System.out.println("Async result: " + future.get()); } } @Service class AsyncService { @Async public CompletableFuture<String> asyncMethod() { try { Thread.sleep(2000); // simulate delay } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return CompletableFuture.completedFuture("Task completed asynchronously"); } }
Output
Calling async method...
Main thread continues...
Async result: Task completed asynchronously
Common Pitfalls
- Forgetting to add
@EnableAsynccauses@Asyncto be ignored. - Calling an
@Asyncmethod from the same class directly bypasses async proxy, so it runs synchronously. - Methods annotated with
@Asyncmust bepublicto work properly. - Return types other than
void,Future, orCompletableFuturewill not work as expected.
java
/* Wrong: Calling async method internally disables async behavior */ @Service public class WrongService { @Async public void asyncMethod() { // runs async only if called from outside } public void caller() { asyncMethod(); // runs synchronously here } } /* Right: Call async method from another bean or self-inject proxy */ @Service public class RightService { private final RightService self; public RightService(RightService self) { this.self = self; } @Async public void asyncMethod() { // runs asynchronously } public void caller() { self.asyncMethod(); // runs asynchronously } }
Quick Reference
Remember these key points when using @Async in Spring Boot:
- Add
@EnableAsyncto your main or config class. - Annotate
publicmethods with@Async. - Use
void,Future, orCompletableFuturereturn types. - Call async methods from other beans to ensure proxy usage.
- Handle exceptions inside async methods carefully.
Key Takeaways
Add @EnableAsync to enable asynchronous method execution in Spring Boot.
Use @Async on public methods to run them in a separate thread asynchronously.
Async methods should return void, Future, or CompletableFuture for proper async handling.
Calling @Async methods internally within the same class bypasses async behavior.
Handle exceptions inside async methods since they run in separate threads.