• 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 运行结果

    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());
    }
    
    

  • 相关阅读:
    datatable里的元素
    ajax
    myeclipse编译项目Webcontent下不生成classes文件
    oracle忘记密码
    zuul的多版本配置
    ribbon灰度发布极简方式
    ribbon灰度发布
    使用网关zuul完成灰度发布
    mybatis-generator代码生成器使用(二)
    mybatis-generator代码生成器使用(一)
  • 原文地址:https://www.cnblogs.com/Grand-Jon/p/10089387.html
Copyright © 2020-2023  润新知