from Understanding Callable and Spring DeferredResult
Callable
Callable: java.util.concurrent.Callable
@RestController
public class AsyncCallableController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final TaskService taskService;
@Autowired
public AsyncCallableController(TaskService taskService) {
this.taskService = taskService;
}
@RequestMapping(value = "/callable", method = RequestMethod.GET, produces = "text/html")
public Callable<String> executeSlowTask() {
logger.info("Request received");
Callable<String> callable = taskService::execute;
logger.info("Servlet thread released");
return callable;
}
}
2015-07-12 13:07:07.012 [nio-8080-exec-5] x.s.w.c.AsyncCallableController : Request received
2015-07-12 13:07:07.013 [nio-8080-exec-5] x.s.w.c.AsyncCallableController : Servlet thread released
2015-07-12 13:07:12.014 [ MvcAsync2] x.spring.web.service.TaskServiceImpl : Slow task executed
controller可以return Callable物件達到非同步的效果
Spring MVC之後會管理TaskExecutor使用不同的thread來執行這個Callable物件的task
DeferredResult
DeferredResult: org.springframework.web.context.request.async.DeferredResult<T>
@RestController
public class AsyncDeferredController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final TaskService taskService;
@Autowired
public AsyncDeferredController(TaskService taskService) {
this.taskService = taskService;
}
@RequestMapping(value = "/deferred", method = RequestMethod.GET, produces = "text/html")
public DeferredResult<String> executeSlowTask() {
logger.info("Request received");
DeferredResult<String> deferredResult = new DeferredResult<>();
CompletableFuture.supplyAsync(taskService::execute)
.whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));
logger.info("Servlet thread released");
return deferredResult;
}
}
2015-07-12 13:28:08.433 [io-8080-exec-10] x.s.w.c.AsyncDeferredController : Request received
2015-07-12 13:28:08.475 [io-8080-exec-10] x.s.w.c.AsyncDeferredController : Servlet thread released
2015-07-12 13:28:13.469 [onPool-worker-1] x.spring.web.service.TaskServiceImpl : Slow task executed
controller也可以return DeferredResult物件達到非同步的效果
但跟Callable不同的是並非由Spring MVC管理
由上例是由CompletableFuture管理使用supplyAsync方法
在ForkJoinPool.commonPool()取得thread執行task後再給DeferredResult物件setResult
其他也可以由JMS或AMQP的message來管理1