How to Enable and Customize Asynchronous Execution in Spring

Learn how to enable Spring's @Async support, configure custom executors, use @Async with void and Future return types, and implement custom exception handling for uncaught async errors, providing a complete guide to asynchronous method execution in Spring applications.

ITFLY8 Architecture Home
ITFLY8 Architecture Home
ITFLY8 Architecture Home
How to Enable and Customize Asynchronous Execution in Spring

Enable Asynchronous Support

@Configuration
@EnableAsync
public class SpringAsyncConfig { ... }

By default, @EnableAsync detects Spring's @Async annotations and can also detect user‑defined annotation types.

Using @Async Annotation

Void return type

@Async
public void asyncMethodWithVoidReturnType() {
    System.out.println("Execute method asynchronously. " + Thread.currentThread().getName());
}

Return type (Future<String>)

@Async
public Future<String> asyncMethodWithReturnType() {
    System.out.println("Execute method asynchronously - " + Thread.currentThread().getName());
    try {
        Thread.sleep(5000);
        return new AsyncResult<String>("hello world !!!!");
    } catch (InterruptedException e) {
        // handle exception
    }
    return null;
}

Executor Configuration

Spring uses SimpleAsyncTaskExecutor by default, which has no thread‑limit. This default can be overridden at method or application level.

Method‑level override

Application‑level override

For application‑level configuration, implement AsyncConfigurer and provide a custom Executor:

@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.initialize();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        return executor;
    }
}

Exception Handling

When a method returns a Future, exceptions are propagated via Future.get(). For void methods, uncaught async exceptions are lost, so a custom handler is required.

Define a handler implementing AsyncUncaughtExceptionHandler:

public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
        System.out.println("Exception message - " + throwable.getMessage());
        System.out.println("Method name - " + method.getName());
        for (Object param : obj) {
            System.out.println("Parameter value - " + param);
        }
    }
}

Then override getAsyncUncaughtExceptionHandler() in the configuration class to return the custom handler:

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new CustomAsyncExceptionHandler();
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

springExecutorAsyncexceptionhandling
ITFLY8 Architecture Home
Written by

ITFLY8 Architecture Home

ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.