当前位置 主页 > 服务器问题 > Linux/apache问题 >
这部分代码在调用完 Servlet
后,会通过 request.isAsync()
来判断是否是异步请求,如果是异步请求,就设置 async = true
。如果是非异步请求就执行输出数据到客户端逻辑,同时销毁 request
和 response
。这里就完成了请求结束后不响应客户端的操作。
为什么说Spring Boot的@EnableAsync注解不是异步Servlet
因为之前准备写本篇文章的时候就查询过很多资料,发现很多资料写SpringBoot异步编程都是依赖于 @EnableAsync
注解,然后在 Controller
用多线程来完成业务逻辑,最后汇总结果,完成返回输出。这里拿一个掘金大佬的文章来举例《新手也能看懂的 SpringBoot 异步编程指南 》,这篇文章写得很通俗易懂,非常不错,从业务层面来说,确实是异步编程,但是有一个问题,抛开业务的并行处理来说,针对整个请求来说,并不是异步的,也就是说不能立即释放Tomcat的线程,从而不能达到异步Servlet的效果。这里我参考上文也写了一个demo,我们来验证下,为什么它不是异步的。
@RestController @Slf4j public class TestController { @Autowired private TestService service; @GetMapping("/hello") public String test() { try { log.info("testAsynch Start"); CompletableFuture<String> test1 = service.test1(); CompletableFuture<String> test2 = service.test2(); CompletableFuture<String> test3 = service.test3(); CompletableFuture.allOf(test1, test2, test3); log.info("test1=====" + test1.get()); log.info("test2=====" + test2.get()); log.info("test3=====" + test3.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } return "hello"; } @Service public class TestService { @Async("asyncExecutor") public CompletableFuture<String> test1() throws InterruptedException { Thread.sleep(3000L); return CompletableFuture.completedFuture("test1"); } @Async("asyncExecutor") public CompletableFuture<String> test2() throws InterruptedException { Thread.sleep(3000L); return CompletableFuture.completedFuture("test2"); } @Async("asyncExecutor") public CompletableFuture<String> test3() throws InterruptedException { Thread.sleep(3000L); return CompletableFuture.completedFuture("test3"); } } @SpringBootApplication @EnableAsync public class TomcatdebugApplication { public static void main(String[] args) { SpringApplication.run(TomcatdebugApplication.class, args); } @Bean(name = "asyncExecutor") public Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(3); executor.setMaxPoolSize(3); executor.setQueueCapacity(100); executor.setThreadNamePrefix("AsynchThread-"); executor.initialize(); return executor; }
这里我运行下,看看效果
这里我请求之后,在调用容器执行业务逻辑之前打了一个断点,然后在返回之后的同样打了一个断点,在 Controller
执行完之后,请求才回到了 CoyoteAdapter
中,并且判断 request.isAsync()
,根据图中看到,是为