Asynchronous Execution in Spring Boot: @Async, CompletableFuture, WebAsyncTask, DeferredResult and Related Optimizations

This article explains multiple ways to perform asynchronous processing in Spring Boot, including @Async annotation, CompletableFuture (supplyAsync, runAsync), WebAsyncTask, DeferredResult, custom AsyncHandlerInterceptor, and server‑side optimizations such as increasing Tomcat connections and switching to Undertow, with complete code examples.

Top Architect
Top Architect
Top Architect
Asynchronous Execution in Spring Boot: @Async, CompletableFuture, WebAsyncTask, DeferredResult and Related Optimizations

The author, a senior architect, introduces asynchronous execution in Spring Boot and presents two main approaches: using the @Async annotation together with @EnableAsync, and leveraging JDK 8's CompletableFuture class.

1. Asynchronous execution with annotations

Apply @Async to a method and add @EnableAsync on the startup class. The framework will run the method in a separate thread pool.

2. Using CompletableFuture

Two examples are provided:

Creating a custom thread that waits on a CompletableFuture result.

Using CompletableFuture.supplyAsync to run a long‑running calc() method without blocking the caller.

@AllArgsConstructor
public class AskThread implements Runnable {
    private CompletableFuture<Integer> re = null;
    public void run() {
        int myRe = 0;
        try {
            myRe = re.get() * re.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(myRe);
    }
    public static void main(String[] args) throws InterruptedException {
        final CompletableFuture<Integer> future = new CompletableFuture<>();
        new Thread(new AskThread(future)).start();
        Thread.sleep(1000);
        future.complete(60);
    }
}

The article notes that CompletableFuture.supplyAsync returns immediately, while the supplied task runs in a new thread (by default the common ForkJoinPool).

3. Additional async utilities CompletableFuture.runAsync(Runnable) for fire‑and‑forget tasks. WebAsyncTask to set a timeout and handle completion callbacks. DeferredResult for long‑running controller responses, with timeout and completion handlers.

Custom AsyncHandlerInterceptor to intercept async processing and modify the response.

CompletableFuture.runAsync(() -> afterBetProcessor(...));
@RestController
public class HelloController {
    @GetMapping("/world")
    public WebAsyncTask<String> worldController() {
        WebAsyncTask<String> task = new WebAsyncTask<>(3000, () -> calc(50));
        task.onTimeout(() -> { throw new TimeoutException("调用超时"); });
        return task;
    }
}

4. Server‑side performance tweaks

Increase embedded Tomcat's maximum connections and threads, and optionally replace Tomcat with Undertow for higher throughput.

@Configuration
public class TomcatConfig {
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers(new MyTomcatConnectorCustomizer());
        factory.setPort(8005);
        factory.setContextPath("/api-g");
        return factory;
    }
    class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer {
        public void customize(Connector connector) {
            Http11NioProtocol p = (Http11NioProtocol) connector.getProtocolHandler();
            p.setMaxConnections(20000);
            p.setMaxThreads(2000);
            p.setConnectionTimeout(30000);
        }
    }
}

Switching to Undertow is shown by replacing the Tomcat starter dependency with spring-boot-starter-undertow.

5. Miscellaneous tips

Using @ComponentScan instead of the broader @SpringBootApplication for faster package scanning.

BufferedWriter for efficient I/O.

DeferredResult based async handling with timeout and completion callbacks.

AsyncHandlerInterceptor implementation that can rewrite the response body.

The article concludes with references to additional resources and invites readers to join a discussion group or request interview question collections.

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.

JavaAsynchronousCompletableFutureSpring Boot
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

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.