Advanced Backend Asynchronous Execution and Configuration Techniques in Spring Boot
This article explains multiple backend optimization methods for Spring Boot, including asynchronous execution with @Async and CompletableFuture, increasing embedded Tomcat connection limits, using @ComponentScan, switching to Undertow, applying BufferedWriter, employing DeferredResult, and intercepting async calls with AsyncHandlerInterceptor, accompanied by concrete code examples.
The article presents a collection of advanced backend techniques for Spring Boot applications, focusing on improving asynchronous processing and server configuration.
1. Asynchronous execution
Two approaches are demonstrated: using the @Async annotation with @EnableAsync, and leveraging Java 8's CompletableFuture for non‑blocking tasks.
@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();
// Simulate long‑running calculation
Thread.sleep(1000);
// Notify completion
future.complete(60);
}
}The example shows a thread waiting for a CompletableFuture result, illustrating how the main thread can continue while the asynchronous task runs.
2. Increase embedded Tomcat maximum connections
@Configuration
public class TomcatConfig {
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory();
tomcatFactory.addConnectorCustomizers(new MyTomcatConnectorCustomizer());
tomcatFactory.setPort(8005);
tomcatFactory.setContextPath("/api-g");
return tomcatFactory;
}
class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer {
public void customize(Connector connector) {
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
// Set max connections
protocol.setMaxConnections(20000);
// Set max threads
protocol.setMaxThreads(2000);
protocol.setConnectionTimeout(30000);
}
}
}This configuration raises the maximum number of connections and threads for the embedded Tomcat server.
3. Use @ComponentScan()
Applying @ComponentScan can be faster than the default @SpringBootApplication component scanning when you need to limit the scan range.
4. Switch default Tomcat container to Undertow
<!-- Exclude Tomcat -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
<!-- Add Undertow -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>Undertow typically offers higher throughput than Tomcat.
5. BufferedWriter buffering
The article mentions using BufferedWriter for I/O buffering, encouraging readers to try it themselves.
6. DeferredResult asynchronous call
@RestController
public class AsyncDeferredController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final LongTimeTask taskService;
@Autowired
public AsyncDeferredController(LongTimeTask taskService) {
this.taskService = taskService;
}
@GetMapping("/deferred")
public DeferredResult<String> executeSlowTask() {
logger.info(Thread.currentThread().getName() + "进入executeSlowTask方法");
DeferredResult<String> deferredResult = new DeferredResult<>();
// Invoke long‑running task
taskService.execute(deferredResult);
logger.info(Thread.currentThread().getName() + "从executeSlowTask方法返回");
// Timeout handling
deferredResult.onTimeout(() -> {
logger.info(Thread.currentThread().getName() + " onTimeout");
deferredResult.setErrorResult("time out!");
});
// Completion handling
deferredResult.onCompletion(() -> logger.info(Thread.currentThread().getName() + " onCompletion"));
return deferredResult;
}
}This demonstrates how Spring MVC can return a DeferredResult to handle long‑running operations without blocking the servlet thread.
7. AsyncHandlerInterceptor interception
@Component
public class MyAsyncHandlerInterceptor implements AsyncHandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MyAsyncHandlerInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.info(Thread.currentThread().getName() + "服务调用完成,返回结果给客户端");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
if (ex != null) {
System.out.println("发生异常:" + ex.getMessage());
}
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Replace original response content
String resp = "my name is chhliu!";
response.setContentLength(resp.length());
response.getOutputStream().write(resp.getBytes());
logger.info(Thread.currentThread().getName() + " 进入afterConcurrentHandlingStarted方法");
}
}The interceptor can modify the response after asynchronous processing, providing a hook for custom logic.
Overall, the article equips developers with practical code snippets and configuration tips to enhance asynchronous processing, scalability, and performance of Spring Boot backend services.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
