0
0
SpringbootHow-ToBeginner · 4 min read

How to Use @EnableAsync in Spring Boot for Async Processing

Use @EnableAsync on a Spring Boot configuration class to activate asynchronous method execution. Then, annotate methods with @Async to run them in a separate thread, improving app responsiveness without blocking the main thread.
📐

Syntax

The @EnableAsync annotation is placed on a configuration class to enable Spring's asynchronous method execution capability. Methods you want to run asynchronously must be annotated with @Async. Spring then runs these methods in a thread pool.

Key parts:

  • @EnableAsync: Enables async support in Spring Boot.
  • @Async: Marks methods to run asynchronously.
  • Configuration class: Usually annotated with @Configuration or @SpringBootApplication.
java
@Configuration
@EnableAsync
public class AsyncConfig {
    // Optional: define Executor bean for thread pool
}

@Service
public class MyService {
    @Async
    public void asyncMethod() {
        // code runs asynchronously
    }
}
💻

Example

This example shows a Spring Boot app with @EnableAsync on the main class and a service method annotated with @Async. When called, the async method runs in a separate thread, allowing the main thread to continue immediately.

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;

@SpringBootApplication
@EnableAsync
public class AsyncExampleApplication {
    public static void main(String[] args) {
        var context = SpringApplication.run(AsyncExampleApplication.class, args);
        MyService service = context.getBean(MyService.class);
        System.out.println("Calling async method...");
        service.asyncMethod();
        System.out.println("Main thread continues...");
    }
}

@Service
class MyService {
    @Async
    public void asyncMethod() {
        try {
            Thread.sleep(2000); // simulate delay
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("Async method finished in thread: " + Thread.currentThread().getName());
    }
}
Output
Calling async method... Main thread continues... Async method finished in thread: task-1
⚠️

Common Pitfalls

Common mistakes when using @EnableAsync include:

  • Not annotating the main configuration class with @EnableAsync, so async support is not activated.
  • Calling @Async methods from within the same class, which bypasses Spring's proxy and runs synchronously.
  • Not returning void or Future/CompletableFuture from async methods, which limits async result handling.
  • Not configuring a thread pool, which can cause performance issues if many async tasks run.

Example of wrong usage:

java
@Service
public class WrongService {
    @Async
    public void asyncMethod() {
        System.out.println("Async method");
    }

    public void callAsync() {
        // This call runs synchronously because it's internal
        this.asyncMethod();
    }
}
📊

Quick Reference

Tips for using @EnableAsync effectively:

  • Always add @EnableAsync on a configuration or main class.
  • Annotate only public methods with @Async for proxy to work.
  • Call async methods from other beans, not internally.
  • Consider defining a custom Executor bean for thread pool tuning.
  • Use CompletableFuture return type to handle async results.

Key Takeaways

Add @EnableAsync on a configuration class to activate async support in Spring Boot.
Use @Async on public methods to run them asynchronously in a separate thread.
Avoid calling @Async methods from the same class to ensure async behavior.
Define a thread pool Executor bean for better async task management.
Async methods can return void or CompletableFuture to handle results.