一:任务
1.任务
使用Runnable异步处理Rest服务
使用DefaultResult异步处理Rest服务
异步处理的配置
2.原理图说明
二:Callable进行异步处理
1.程序
新建一个anysc的包
1 packagecom.cao.web.async;2
3 importjava.util.concurrent.Callable;4
5 importorg.slf4j.Logger;6 importorg.slf4j.LoggerFactory;7 importorg.springframework.web.bind.annotation.RequestMapping;8 importorg.springframework.web.bind.annotation.RestController;9
10 @RestController11 public classAsyncController {12 private Logger logger=LoggerFactory.getLogger(getClass());13
14 @RequestMapping("/order")15 public Callable order() throwsException {16 logger.info("主线程开始");17 //业务逻辑放在副线程中
18 Callable result=new Callable() {19
20 @Override21 public String call() throwsException {22 logger.info("副线程开始");23 Thread.sleep(5000);24 logger.info("副线程返回");25 return "success";26 }27
28 };29
30 logger.info("主线程返回");31
32 returnresult;33 }34
35 }
2.效果
重点关注时间
三:使用DeferredResult
1.问题
方式一是有问题的,因为副线程是需要主线程调用起来的。
是写在主线程中的。
有些场景是不合适的。
线程间使用DeferredResult沟通起来。
2.场景如下:
3.程序
程序太多,有点复杂
控制器
1 packagecom.cao.web.async;2
3 importjava.util.concurrent.Callable;4
5 importorg.apache.commons.lang.RandomStringUtils;6 importorg.slf4j.Logger;7 importorg.slf4j.LoggerFactory;8 importorg.springframework.beans.factory.annotation.Autowired;9 importorg.springframework.web.bind.annotation.RequestMapping;10 importorg.springframework.web.bind.annotation.RestController;11 importorg.springframework.web.context.request.async.DeferredResult;12
13 @RestController14 public classAsyncController {15 private Logger logger=LoggerFactory.getLogger(getClass());16 @Autowired17 privateQueue queue;18
19 @Autowired20 privateDeferredResultHolder deferredResultHolder;21
22 /**
23 * 主要是验证Callable24 *@return
25 *@throwsException26 */
27 @RequestMapping("/order")28 public Callable order() throwsException {29 logger.info("主线程开始");30 //业务逻辑放在副线程中
31 Callable result=new Callable() {32
33 @Override34 public String call() throwsException {35 logger.info("副线程开始");36 Thread.sleep(5000);37 logger.info("副线程返回");38 return "success";39 }40
41 };42
43 logger.info("主线程返回");44
45 returnresult;46 }47 /**
48 * 主要是验证49 *@return
50 *@throwsException51 */
52 @RequestMapping("/newOrder")53 public DeferredResult newOrder() throwsException {54 logger.info("主线程开始");55 //56 String oderNumber=RandomStringUtils.randomNumeric(8);57 queue.setPlaceOrder(oderNumber);58 DeferredResult result=new DeferredResult<>();59 deferredResultHolder.getMap().put(oderNumber, result);60 logger.info("主线程返回");61
62 returnresult;63 }64
65 }
queue.java
1 packagecom.cao.web.async;2
3 importorg.slf4j.Logger;4 importorg.slf4j.LoggerFactory;5 importorg.springframework.stereotype.Component;6
7 @Component8 public classQueue {9 privateString placeOrder;10 privateString completeOrder;11
12 private Logger logger=LoggerFactory.getLogger(getClass());13
14 publicString getPlaceOrder() {15 returnplaceOrder;16 }17 public void setPlaceOrder(String placeOrder) throwsException {18 new Thread(() ->{19 logger.info("接到下单请求");20 try{21 Thread.sleep(2000);22 } catch(InterruptedException e) {23 e.printStackTrace();24 }25 //表示处理完成,应用2将结果返回给了completeOrder
26 this.completeOrder =placeOrder;27 logger.info("下单请求处理完毕" +placeOrder);28 }29
30 ).start();31
32 }33 publicString getCompleteOrder() {34 returncompleteOrder;35 }36 public voidsetCompleteOrder(String completeOrder) {37 this.completeOrder =completeOrder;38 }39
40 }
deferredResultHolder.java
1 packagecom.cao.web.async;2
3 importjava.util.HashMap;4 importjava.util.Map;5
6 importorg.springframework.stereotype.Component;7 importorg.springframework.web.context.request.async.DeferredResult;8
9 @Component10 public classDeferredResultHolder {11 //一个是订单号,一个是订单号的处理结果
12 private Map> map=new HashMap<>();13 public Map>getMap(){14 returnmap;15 }16 public void setMap(Map>map) {17 this.map=map;18 }19 }
QueueListener.java
1 packagecom.cao.web.async;2
3 import staticorg.springframework.test.web.servlet.result.MockMvcResultHandlers.log;4
5 importorg.apache.commons.lang.StringUtils;6 importorg.slf4j.Logger;7 importorg.slf4j.LoggerFactory;8 importorg.springframework.beans.factory.annotation.Autowired;9 importorg.springframework.context.ApplicationListener;10 importorg.springframework.context.event.ContextRefreshedEvent;11 importorg.springframework.stereotype.Component;12
13 @Component14 public class QueueListener implements ApplicationListener{15 @Autowired16 privateQueue queue;17
18 @Autowired19 privateDeferredResultHolder deferredResultHolder;20
21 private Logger logger=LoggerFactory.getLogger(getClass());22
23 @Override24 public voidonApplicationEvent(ContextRefreshedEvent event) {25 new Thread(() ->{26 while (true) {27 if(StringUtils.isNotBlank(queue.getCompleteOrder())) {28 String orderNumber =queue.getCompleteOrder();29 logger.info("返回订单处理结果" +orderNumber);30 deferredResultHolder.getMap().get(orderNumber).setResult("place order success");31 queue.setCompleteOrder(null);32 } else{33 try{34 Thread.sleep(100);35 } catch(InterruptedException e) {36 //TODO Auto-generated catch block
37 e.printStackTrace();38 }39 }40 }41 }).start();42
43
44 }45
46
47 }
4.效果
前端效果
控制台效果
三:异步线程的配置
1.说明
对于拦截器,与同步的拦截器不一样,仍然需要配置、
2.主要配置