spring-boot-data-aggregator Spring Boot Data Bean 开源项目

我要开发同款
匿名用户2019年06月10日
88阅读

技术信息

开源地址
https://github.com/lvyahui8/spring-boot-data-aggregator
授权协议
Apache

作品详情

背景与目的

在开发后台接口时,为了开发效率,我们往往习惯编写串行执行的代码,去调用不同的接口,即使这些接口之间并无依赖,这使得最后开发的接口性能低下,且数据不方便复用

此框架目的旨在保持开发效率的同时,很方便地支持并发和数据复用

当然,在极端高并发的场景下,并行调用接口对性能提升并不明显,但不代表这个项目没有价值.因为互联网世界的大部分应用,并不会有非常高的并发访问量

原理CoutDowLatch+Future+递归为了得到目标数据,会递归分析并获取数据做需要的依赖项, 数据的依赖项有两种:其他接口返回值或者输入参数,前一种需要调用其他接口,这个调用将封装为任务异步执行并获取结果特性

异步获取依赖

所有 @DataCosumer 定义的依赖将异步获取.当provider方法参数中的所有依赖获取完成,才执行provider方法

不限级嵌套

依赖关系支持深层嵌套.下面的示例只有一层

异常处理

目前支持两种处理方式:忽略or终止

忽略是指provider方法在执行时,忽略抛出的异常并returull值;终止是指一旦有一个provider方法抛出了异常,将逐级向上抛出,终止后续处理.

配置支持cosumer级或者全局,优先级:cosumer级>全局

查询缓存

在调用Facade的query方法的一次查询生命周期内, 方法调用结果可能复用,只要方法签名以及传参一致,则默认方法是幂等的,将直接使用缓存的查询结果. 但这个不是绝对的,考虑到多线程的特性,可能有时候不会使用缓存

超时控制

@DataProvider 注解支持配置timeout,超时将抛出中断异常(IterruptedExceptio),遵循异常处理逻辑

使用方法

pom.xml

<depedecy><groupId>io.github.lvyahui8</groupId><artifactId>sprig-boot-data-aggregator-starter</artifactId><versio>1.0.2</versio></depedecy>

applicatio.properties

#指定要扫描注解的包io.github.lvyahui8.sprig.base-packages=io.github.lvyahui8.sprig.example@DataProvider 定义数据提供者@DataCosumer 定义方法参数依赖类型为其他接口返回值,其他接口是一个@DataProvider@IvokeParameter 定义方法参数依赖类型为用户输入值SprigBea DataBeaAggregateQueryFacade 查询指定的数据的门面示例

开发一个用户汇总数据接口,包括用户的基础信息和博客列表

1.定义提供基础数据的"原子"服务

使用@DataProvider定义接口为数据提供者

使用@IvokeParameter指定要传递的用户输入参数

博客列表服务

需要参数userId

@ServicepublicclassPostServiceImplimplemetsPostService{@DataProvider("posts")@OverridepublicList<Post>getPosts(@IvokeParameter("userId")LoguserId){try{Thread.sleep(1000L);}catch(IterruptedExceptioe){//}Postpost=ewPost();post.setTitle("sprigdataaggregateexample");post.setCotet("Noactiveprofileset,falligbacktodefaultprofiles");returCollectios.sigletoList(post);}}

用户基础信息查询服务

需要参数userId

@ServicepublicclassUserServiceImplimplemetsUserService{@DataProvider("user")@OverridepublicUserget(@IvokeParameter("userId")Logid){/**/try{Thread.sleep(100L);}catch(IterruptedExceptioe){//}/*mockauser*/Useruser=ewUser();user.setId(id);user.setEmail("lvyahui8@gmail.com");user.setUserame("lvyahui8");returuser;}}2.定义并实现聚合层

组合@DataProvider \ @DataCosumer \ @IvokeParameter 实现汇聚功能

@CompoetpublicclassUserAggregate{@DataProvider("userWithPosts")publicUseruserWithPosts(@DataCosumer("user")Useruser,@DataCosumer("posts")List<Post>posts){user.setPosts(posts);returuser;}}3.调用聚合层接口

注解了@DataProvider方法的接口不需要直接调用,而是通过门面类DataBeaAggregateQueryFacade访问.

指定要查询的dataid,查询参数,返回值类型,并调用facade.get方法即可

DataBeaAggregateQueryFacadequeryFacade=cotext.getBea(DataBeaAggregateQueryFacade.class);Useruser=queryFacade.get(/*dataid*/"userWithPosts",/*IvokeParameters*/Collectios.sigletoMap("userId",1L),User.class);Assert.otNull(user,"userotull");Assert.otNull(user.getPosts(),"userpostsotull");

运行结果

可以看到,user和posts是由异步线程执行查询,而userWithPosts是主调线程执行,其中

基础user信息查询耗费时间1000ms用户博客列表查询耗费时间1000ms总的查询时间1005ms[aggregateTask-1]queryid:user,costTime:1000ms,resultType:User,ivokeMethod:UserServiceImpl#get[aggregateTask-2]queryid:posts,costTime:1000ms,resultType:List,ivokeMethod:PostServiceImpl#getPosts[mai]queryid:userWithPosts,costTime:1010ms,resultType:User,ivokeMethod:UserAggregate#userWithPosts[mai]user.ame:lvyahui8,user.posts.size:1

功能介绍

背景与目的 在开发后台接口时, 为了开发效率, 我们往往习惯编写串行执行的代码, 去调用不同的接口, 即使这些接口之间并无依赖, 这使得最后开发的接口性能低下, 且数据不方便复用 此框架目的旨在...

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论