当前位置: 首页 > article >正文

CompletableFuture 实战

        在本文章中通过一个案例来演示一下CompletableFuture的使用。
        以一个商品查询为例,在微服务架构中,一个商品信息查询会涉及商品基本信息查询、商品评论查询、商品库存查询,每个查询都涉及不同的微服务的调用,如果使用异步编程的方式,应该如何实现呢?
        当前演示的案例项目是采用Spring Boot构建的,其中涉及如下类。

  •         Goods,商品实体对象。
  •         独立微服务:                    

                     GoodsService,商品基本信息服务

                     RepoService,商品库存信息服务

                     CommentService,商品评论信息服务。

         

        GoodsController,Web 请求。

注意:为了尽量减少和本书中无关内容的引入,下面的代码简化了远程通信模块,直接采用
本地调用方式来模拟远程通信。


商品实体对象


商品实例对象类Goods定义如下。

@Getter
@Data
public class Goods {
    private Integer id;
    //商品名称
    private String name;
    //价格
    private BigDecimal price;
    //库存
    private Integer repo;
    //购买人数
    private Integer buyerNum;
    //评价
    private List<String> comment;
    public Goods(Integer id, string name, BigDecimal price){
        this.id = id; 
        this.name = name; 
        this.price = price;
    }
}

模拟微服务请求实现类


商品评价信息服务类CommentService定义如下。

@Service
public class CommentService {
    /**
    * 返回指定商品的评论
    * @return
    */
    public List<String> getCommentsByGoodsId(Integer goodsId) {
        return Arrays.asList("好","一般","很好");
    }
}

商品基本信息查询服务类GoodsService定义如下。
 

@Service
public class GoodsService {

    /**
    * 查询商品信息
    * @return
    */
    public List<Goods> queryGoods(){
        return Arrays.asList(
            new Goods(1,"电脑",newBigDecimal(5000)), 
            new Goods(2,"手机",newBigDecimal(3000)), 
            new Goods(3,"书",new BigDecimal(99)), 
            new Goods(4,"杯子",newBigDecimal(18)));
    }
}


    商品库存查询服务类RepoService定义如下。

@Service
public class RepoService {
    /**
    * 查询指定商品库存
    * @param goodsId
    * @return
    */
    public Integer getRepoByGoodsId(Integer goodsId){
        return new Random( ) .nextInt(1000);
    }
}

Web请求


        GoodsController类提供HTTP接口服务,用来访问商品详细信息,代码如下。

@RestController
public class GoodsController {
    @Autowired
    GoodsService goodsService;
    @Autowired
    CommentService commentService;

    @Autowired
    RepoService repoService;
    @GetMapping("/goods")
    public List<Goods> goods() throws ExecutionException, InterruptedException{
            CompletableFuture<List<Goods>>goodsFuture = CompletableFuture.supplyAsync(()->goodsService.queryGoods());
            CompletableFuture cf=goodsFuture.thenApplyAsync(goods->{
                goods.stream( ).map(good1->CompletableFuture.supplyAsync(()->{
                    good1.setRepo(repoService.getRepoByGoodsId(good1.getId())); 
                    return good1;
                }).thenCompose(good2->CompletableFuture.supplyAsync(()->{
                    good2.setComment(commentService.getCommentsByGoodsId(good2.getId())); 
                    return good2;
                }))).toArray(size->new CompletableFuture[size]); 
                return goods;
            });
            return (List<Goods>) cf.handleAsync((goods,th)->th!=nul1?"系统繁忙":goods).get( );
    }
}

其功能说明如下。

  • 使用supplyAsync()方法来构建一个CompletableFuture任务,这个任务负责查询所有商品的基本信息。
  • 接着通过thenApplyAsyne()方法来连接另外一个任务,也就是当第一个查询商品基本信息的 CompletinStage任务执行结束后,通过异步线程执行第二个任务。
  • 在第二个任务中,使用了thenCompose()方法来组合两个CompletionStage任务,完成商品评论和商品库存信息的补充。
  • 最终采用handleAsync()方法返回执行结果,这里用handleAsyncO方法的目的是避免将前置任务的异常直接抛给前端。

        总的来说,了解了CompletionStage中不同类型的方法之后,就可以随心所欲地在实际业务场景中使用了,建议各位兄弟根据自己的实际业务场景来判断是否有必要使用,然后根据需求尝试合理地应用,从而更好地理解CompletableFuture。


        兄弟们,先消化一下上面的内容吧,接下来的文章会带领我们了解一下CompletableFuture的实现原理,敬请期待^_^


http://www.kler.cn/news/107792.html

相关文章:

  • 公网远程访问macOS本地web服务器
  • 23种设计模式(10)——门面模式
  • css:如何通过不同的值,改变盒子的样式和字体颜色通过computed而不是v-if
  • Operator开发之operator-sdk入门
  • XMLHttpRequest拦截请求和响应
  • Unity性能优化一本通
  • YOLOv5 onnx \tensorrt 推理
  • uniapp接口请求api封装,规范化调用
  • Go 实现插入排序算法及优化
  • 软考系列(系统架构师)- 2013年系统架构师软考案例分析考点
  • 5月22日比特币披萨日,今天你吃披萨了吗?
  • 【计算机网络】认识协议
  • Spring Boot拓展XML格式的请求和响应
  • 『Jmeter入门万字长文』 | 从环境搭建、脚本设计、执行步骤到生成监控报告完整过程
  • leetCode 229. 多数元素 II + 摩尔投票法 + 进阶 + 优化空间
  • Linux:【1】Linux中的文件权限概念和相关命令
  • Hive 视图和索引
  • Spring Security—配置(Configuration)
  • 命令行参数、环境变量
  • 集合总结(Java)
  • JavaScript_Pig Game切换当前玩家
  • 【Linux】权限完结
  • 从lc560“和为 K 的子数组“带你认识“前缀和+哈希表“的解题思路
  • 【iPad已停用】解锁教程
  • 现代挖掘机vr在线互动展示厅是实现业务增长的加速度
  • Java集合-HashMap源码分析
  • Docker多平台、跨平台编译打包
  • 【ChatGPT系列】ChatGPT:创新工具还是失业威胁?
  • spark3.3.x处理excel数据
  • 【Python机器学习】零基础掌握RandomForestClassifier集成学习