Spring中注解方式的异步请求

作者:煎丶包 时间:2023-11-30 18:53:54 

一、Servlet3.0异步请求


@WebServlet(value = "/async", asyncSupported = true)
public class HelloAsyncServlet extends HttpServlet {

@Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //1、设置支持异步处理asyncSupported = true
       //2、开启异步模式
       System.out.println("主线程开始:" + Thread.currentThread() + "==>" + System.currentTimeMillis());
       AsyncContext startAsync = req.startAsync();
       //3、业务逻辑进行异步处理,开始异步处理
       startAsync.start(new Runnable() {
           @Override
           public void run() {
               try {
                   System.out.println("副线程开始:" + Thread.currentThread() + "==>" + System.currentTimeMillis());
                   sayHello();
                   //获取到异步的上下文
                   AsyncContext asyncContext = req.getAsyncContext();
                   startAsync.complete();
                   ServletResponse response = asyncContext.getResponse();
                   response.getWriter().write("hello async!");
                   System.out.println("副线程结束:" + Thread.currentThread() + "==>" + System.currentTimeMillis());
               } catch (Exception e) {
                   e.printStackTrace();
               }

}
       });
       System.out.println("主线程结束:" + Thread.currentThread() + "==>" + System.currentTimeMillis());
   }

public void sayHello() throws Exception {
       System.out.println(Thread.currentThread() + "processing...");
       Thread.sleep(3000);
   }
}

打印结果:

Spring中注解方式的异步请求

二、SpringMVC的异步请求

返回Callable


@Controller
public class AsyncController {

@ResponseBody
   @RequestMapping("/async01")
   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(2000);
               System.out.println("副线程开始:" + Thread.currentThread() + "==>" + System.currentTimeMillis());

return "async01";
           }
       };

System.out.println("主线程结束:" + Thread.currentThread() + "==>" + System.currentTimeMillis());
       return callable;

}
}
  • 控制器返回Callable

  • Spring进行异步处理,将Callable提交给TaskExecutor,使用一个隔离的线程进行执行

  • DispatcherServlet和所有的Filter退出Web容器的线程,但是response保持打开状态

  • Callable返回结果,SpreingMVC将请求重新派发给容器,恢复之前的处理,Callable返回值就是目标方法的返回值

  • 根据Callable返回的结果,SpringMVC继续进行视图渲染流程等(从收到请求到视图渲染)

输出结果:

Spring中注解方式的异步请求

返回DeferredResult

模拟一个消息中间件


public class DeferredResultQueue {

private static Queue<DeferredResult<Object>> queue = new ConcurrentLinkedDeque<DeferredResult<Object>>();

public static void save(DeferredResult<Object> deferredResult){
       queue.add(deferredResult);
   }

public static DeferredResult<Object> get(){
       return queue.poll();
   }
}

/createOrder请求会暂时保存DeferredResultQueue中,/create请求会获取DeferredResultQueue中的请求,进行业务逻辑的处理并返回结果


@Controller
public class AsyncController {

@ResponseBody
   @RequestMapping("/createOrder")
   public DeferredResult<Object> createOrder(){
       DeferredResult<Object> deferredResult = new DeferredResult<Object>((long)3000,"create fail");

DeferredResultQueue.save(deferredResult);

return deferredResult;
   }

@ResponseBody
   @RequestMapping("/create")
   public String create(){

String order = UUID.randomUUID().toString();
       DeferredResult<Object> deferredResult = DeferredResultQueue.get();
       deferredResult.setResult(order);
       return "success:" + order;
   }
}

来源:https://blog.csdn.net/qq_39794062/article/details/117512875

标签:Spring,注解方式,异步请求
0
投稿

猜你喜欢

  • 使用IDEA搭建SSM框架的详细教程(spring + springMVC +MyBatis)

    2023-04-24 07:35:45
  • Android使用WindowManager构造悬浮view

    2022-08-03 00:43:13
  • Kotlin协程flowOn与线程切换超详细示例介绍

    2022-11-06 08:31:51
  • Java实现单向链表的基本功能详解

    2022-12-18 10:57:02
  • java秒杀之redis限流操作详解

    2022-07-08 09:26:57
  • Spring工作原理简单探索

    2023-04-26 10:30:56
  • IntelliJ IDEA 如何配置git的操作方法

    2021-12-28 11:24:44
  • Spring实战之使用ClassPathResource加载xml资源示例

    2023-11-28 23:00:30
  • OpenCV计算图像的水平和垂直积分投影

    2021-10-09 08:40:45
  • Spring Boot 集成Elasticsearch模块实现简单查询功能

    2022-09-05 06:31:31
  • 详解Java数据库连接JDBC基础知识(操作数据库:增删改查)

    2023-08-22 23:47:37
  • VS2015为console.readkey添加代码片段的方法

    2023-11-15 05:23:41
  • android 实现侧边弹窗特效代码

    2021-10-18 07:23:02
  • C# CSV文件读写的实现

    2023-05-24 10:39:07
  • 解决@Autowired注入static接口的问题

    2022-01-02 03:16:29
  • Java中MyBatis Plus知识点总结

    2023-08-11 14:12:04
  • Android三种网络通讯方式及Android的网络通讯机制

    2021-08-20 12:54:31
  • java swing中实现拖拽功能示例

    2023-09-15 11:46:42
  • mybatis @InsertProvider报错问题及解决

    2023-09-27 15:49:59
  • Java获取任意http网页源代码的方法

    2022-07-06 01:45:37
  • asp之家 软件编程 m.aspxhome.com