异步

配置springmvc的异步

开启Spring MVC支持配置:继承 WebMvcConfigurerAdapter 的配置类DemoMVCConfig

@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(30*1000L); //tomcat默认10秒
configurer.setTaskExecutor(mvcTaskExecutor());//所借助的TaskExecutor
}

@Bean
public ThreadPoolTaskExecutor mvcTaskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setQueueCapacity(100);
executor.setMaxPoolSize(25);
return executor;
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/async").setViewName("/async");
}

return Callable

// After
@RequestMapping(method=RequestMethod.POST)
public Callable<String> processUpload(final MultipartFile file) {

return new Callable<String>() {
public Object call() throws Exception {
// ...
return "someView";
}
};
}

return WebAsyncTask

@RequestMapping(value="/longtimetask", method = RequestMethod.GET)
public WebAsyncTask longTimeTask(){
System.out.println("/longtimetask被调用 thread id is : " + Thread.currentThread().getId());
Callable<ModelAndView> callable = new Callable<ModelAndView>() {
public ModelAndView call() throws Exception {
Thread.sleep(3000); //假设是一些长时间任务
ModelAndView mav = new ModelAndView("longtimetask");
mav.addObject("result", "执行成功");
System.out.println("执行成功 thread id is : " + Thread.currentThread().getId());
return mav;
}
};
return new WebAsyncTask(callable);
}

其核心是一个 Callable<ModelAndView>,事实上,直接返回 Callable<ModelAndView> 都是可以的,但我们这里包装了一层,以便做后面提到的**“超时处理”**。

@RequestMapping(value="/longtimetask", method = RequestMethod.GET)
public WebAsyncTask longTimeTask(){
System.out.println("/longtimetask被调用 thread id is : " + Thread.currentThread().getId());

Callable<ModelAndView> callable = new Callable<ModelAndView>() {
public ModelAndView call() throws Exception {
Thread.sleep(3000); //假设是一些长时间任务
ModelAndView mav = new ModelAndView("longtimetask");
mav.addObject("result", "执行成功");
System.out.println("执行成功 thread id is : " + Thread.currentThread().getId());
return mav;
}
};

WebAsyncTask asyncTask = new WebAsyncTask(2000, callable);
asyncTask.onTimeout(
new Callable<ModelAndView>() {
public ModelAndView call() throws Exception {
ModelAndView mav = new ModelAndView("longtimetask");
mav.addObject("result", "执行超时");
System.out.println("执行超时 thread id is :" + Thread.currentThread().getId());
return mav;
}
}
);
return new WebAsyncTask(3000, callable);
}

return DeferredResult

DeferredResult (new type in Spring MVC 3.2) to complete processing in a thread not known to Spring MVC.

@RequestMapping("/quotes")
@ResponseBody
public DeferredResult<String> quotes() {
DeferredResult<String> deferredResult = new DeferredResult<String>();
// Add deferredResult to a Queue or a Map...
return deferredResult;
}


// In some other thread...
deferredResult.setResult(data);
// Remove deferredResult from the Queue or Map

good

@GetMapping("/hello3/{latency}")
public DeferredResult<String> hello3(@PathVariable long latency) {
DeferredResult<String> deferredResult = new DeferredResult<String>();

CompletableFuture.supplyAsync(() -> TestController.doSomething(latency))
.whenCompleteAsync(
(result, throwable) -> deferredResult.setResult(result));

return deferredResult;
}