场景
生产中,往往会遇到这样的情景,controller 中调用的方法很多都是和第三方有关的,例如 JMS,定时任务,队列等,拿 JMS 来说,比如 controller 里面的服务需要从 JMS 中拿到返回值,才能给客户端返回,而从 JMS 拿值这个过程也是异步的,这个时候,我们就可以通过 Deferred 来实现整个的异步调用。
如果只使用 Async 方式,虽然开启了异步处理方式,但是拿不到返回结果。
而 Deferred 方式,不仅通过 Async 开启了异步线程,而且还能获取到异步处理结果,一定程度提高了系统的吞吐量。
实现
首先,模拟一个长时间调用的任务,代码如下:
1 |
|
Tips:启动类需要增加 @EnableAsync
注解
接着,实现异步调用,controller 如下:
1 |
|
异步调用可以使用 AsyncHandlerInterceptor 进行拦截,使用示例如下:
1 |
|
执行结果如下:
1 | 2017-12-07 19:25:40.192 INFO 6196 --- [nio-8060-exec-7] c.t.controller.AsyncDeferredController : http-nio-8060-exec-7 进入 executeSlowTask 方法 |
从上面的执行结果不难看出,容器线程会立刻返回,应用程序使用线程池里面的 cTaskExecutor-1 线程来完成长时间任务的调用,当调用完成后,容器又启了一个连接线程,来返回最终的执行结果。
这种异步调用,在容器线程资源非常宝贵的时候,能够大大的提高整个系统的吞吐量。