0
0
SpringbootHow-ToBeginner · 4 min read

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, CompletableFuture for 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 @EnableAsync causes @Async to be ignored.
  • Calling an @Async method from the same class directly bypasses async proxy, so it runs synchronously.
  • Methods annotated with @Async must be public to work properly.
  • Return types other than void, Future, or CompletableFuture will 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 @EnableAsync to your main or config class.
  • Annotate public methods with @Async.
  • Use void, Future, or CompletableFuture return 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.