zoukankan      html  css  js  c++  java
  • 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());
    }
    
    

  • 相关阅读:
    Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务
    JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数
    java.net.UnknownHostException: lc001 未知的网络服务
    Maven 多模块引用版本的问题 java.lang.NoSuchMethodError
    Maven项目运行Junit测试用例 出现ClassNotFound
    CAS5.X 集群配置 初版
    调试CAS源码步骤
    openhtmltopdf 支持自定义字体、粗体
    Java HTML to PDF 支持SVG
    .Net 框架
  • 原文地址:https://www.cnblogs.com/Grand-Jon/p/10089387.html
Copyright © 2011-2022 走看看