60、springmvc-异步请求-返回Callable

60、springmvc-异步请求-返回Callable

@Controller
public class AsyncController {

    @RequestMapping("async01")
    @ResponseBody
    public Callable<String> async01() {

        System.out.println("主线程开始..." + Thread.currentThread() + "===》" + System.currentTimeMillis());
        Callable<String> callable = new Callable<String>() {
            public String call() throws Exception {
                System.out.println("子线程开始..." + Thread.currentThread() + "===》" + System.currentTimeMillis());
                Thread.sleep(3000);
                System.out.println("子线程结束..." + Thread.currentThread() + "===》" + System.currentTimeMillis());
                return "Callable<String> async01()";
            }
        };
        System.out.println("主线程结束..." + Thread.currentThread() + "===》" + System.currentTimeMillis());
        return callable;
    }
}
60.1 Spring MVC异步执行
  1. 控制器返回Callable
  2. Spring异步处理,将Callable 提交到 TaskExecutor 使用一个隔离的线程进行执行
  3. DispatcherServlet和所有的Filter退出web容器的线程,但是response 保持打开状态;
  4. Callable返回结果,SpringMVC将请求重新派发给容器,恢复之前的处理;
  5. 根据Callable返回的结果。SpringMVC继续进行视图渲染流程等(从收请求-视图渲染)。
60.2 运行结果

1221855-20181219121147634-1765440284.png

60.3 异步拦截器
  1. 原生API的AsyncListener
  2. SpringMVC:实现AsyncHandlerInterceptor
60.4 注意警告。
  • 查看执行类源码 org.springframework.web.context.request.async.WebAsyncManager 有这么一段获取
  • 如果没有指定 AsyncTaskExecutor 就会 warning 警告 logExecutorWarning();
AsyncTaskExecutor executor = webAsyncTask.getExecutor();
if (executor != null) {
    this.taskExecutor = executor;
}
else {
    logExecutorWarning();
}
  • 解决:我们可以自己配置一个线程池来执行,如下
  • 通过在AppConfig implements WebMvcConfigurerconfigurer.setTaskExecutor(threadPoolTaskExecutor());来执行
/**
 * 自定义 异步任务执行线程池,解决warnning警告
 * @return
 */
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.initialize();
    executor.setCorePoolSize(10);
    executor.setMaxPoolSize(50);
    executor.setThreadNamePrefix("JHW");
    return executor;
}

@Bean
public TimeoutCallableProcessingInterceptor timeoutCallableProcessingInterceptor() {
    return new TimeoutCallableProcessingInterceptor();
}

public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    configurer.setTaskExecutor(threadPoolTaskExecutor());
    configurer.setDefaultTimeout(60 * 1000L);
    configurer.registerCallableInterceptors(timeoutCallableProcessingInterceptor());
}

1221855-20181219145811264-808032925.png

转载于:https://www.cnblogs.com/Grand-Jon/p/10089387.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值