All Projects → lvyahui8 → Spring Boot Data Aggregator

lvyahui8 / Spring Boot Data Aggregator

Licence: apache-2.0
基于注解实现并行地依赖注入(数据聚合),可以看做 Spring Async 注解的升级版

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Spring Boot Data Aggregator

Important Java Concepts
🚀 Complete Java - A to Z ║ 📚 Notes and Programs of all Important Concepts of Java - OOPS, Data Structures, Algorithms, Design Patterns & Development + Kotlin + Android 🔥
Stars: ✭ 135 (-4.93%)
Mutual labels:  concurrency, spring-boot
Parallel
Parallel processing for PHP based on Amp.
Stars: ✭ 478 (+236.62%)
Mutual labels:  concurrency, parallel-processing
java-multithread
Códigos feitos para o curso de Multithreading com Java, no canal RinaldoDev do YouTube.
Stars: ✭ 24 (-83.1%)
Mutual labels:  concurrency, parallel-processing
Hamsters.js
100% Vanilla Javascript Multithreading & Parallel Execution Library
Stars: ✭ 517 (+264.08%)
Mutual labels:  concurrency, parallel-processing
Atom
Java course materials
Stars: ✭ 293 (+106.34%)
Mutual labels:  concurrency, spring-boot
Java Interview
At the beginning, it was the repository with questions from Java interviews. Currently, it's more like knowledge base with useful links.
Stars: ✭ 114 (-19.72%)
Mutual labels:  concurrency, spring-boot
Grpc Spring Boot Starter
Spring Boot starter module for gRPC framework.
Stars: ✭ 1,829 (+1188.03%)
Mutual labels:  spring-boot
Spring Boot Jwt
a simple Demo of securing Spring boot rest endpoints using JWT
Stars: ✭ 138 (-2.82%)
Mutual labels:  spring-boot
Advanced Http4s
🌈 Code samples of advanced features of Http4s in combination with some features of Fs2 not often seen.
Stars: ✭ 136 (-4.23%)
Mutual labels:  concurrency
Tmtoolkit
Text Mining and Topic Modeling Toolkit for Python with parallel processing power
Stars: ✭ 135 (-4.93%)
Mutual labels:  parallel-processing
Websocketdemo
在Spring Boot中使用WebSocket,示例包括简单模式、STOMP模式消息、处理对方不在线情况、分布式WebSocket等。
Stars: ✭ 140 (-1.41%)
Mutual labels:  spring-boot
Spring Cloud Cli
Spring Cloud CLI features
Stars: ✭ 139 (-2.11%)
Mutual labels:  spring-boot
Gemini
Model Driven REST framework to automatically generate CRUD APIs
Stars: ✭ 138 (-2.82%)
Mutual labels:  spring-boot
Spring Boot Demo
Spring Boot的基础教程,由浅入深,一步一步学习Spring Boot,最后学到的不单单是基础!Spring Cloud基础教程请看:https://github.com/roncoo/spring-cloud-demo
Stars: ✭ 1,687 (+1088.03%)
Mutual labels:  spring-boot
Spring Cloud Yes
基于Spring Cloud的快速开发脚手架&最佳实践总结
Stars: ✭ 138 (-2.82%)
Mutual labels:  spring-boot
Sivalabs Blog Samples Code
Code samples for my blog posts on https://sivalabs.in
Stars: ✭ 139 (-2.11%)
Mutual labels:  spring-boot
Spring Cloud Config
External configuration (server and client) for Spring Cloud
Stars: ✭ 1,740 (+1125.35%)
Mutual labels:  spring-boot
Spring Boot Vuejs
Example project showing how to build a Spring Boot App providing a GUI with Vue.js
Stars: ✭ 1,818 (+1180.28%)
Mutual labels:  spring-boot
Roncoo Jui Springboot
基于Spring Boot框架,前台框架为JUI的后台框架,功能会继续添加,欢迎大家star和fork!该项目是为了大家更好地运用Spring Boot的功能,进行实战。如果没有使用过Spring Boot,也是一个学习的好项目。可以快速实现一个基于Spring Boot的后台管理系统,前端是基于JUI。
Stars: ✭ 139 (-2.11%)
Mutual labels:  spring-boot
Accelerator
The Accelerator is a tool for fast and reproducible processing of large amounts of data.
Stars: ✭ 137 (-3.52%)
Mutual labels:  parallel-processing

Spring Boot 并行数据聚合库

Build Status Codecov License Maven Central GitHub release

Total alerts Language grade: Java

基于注解实现并行地依赖注入(调用),可以看做 Spring @Async 注解的升级版。

image-20200309230202047

特性

  • 异步获取依赖

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

  • 不限级嵌套

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

  • 异常处理

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

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

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

  • 查询缓存

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

  • 超时控制

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

使用方法

1. 配置

pom.xml

<dependency>
  <groupId>io.github.lvyahui8</groupId>
  <artifactId>spring-boot-data-aggregator-starter</artifactId>
  <version>{$LATEST_VERSION}</version>
</dependency>

application.properties

# 指定要扫描注解的包
io.github.lvyahui8.spring.base-packages=io.github.lvyahui8.spring.example

2. 添加注解

  • @DataProvider 定义数据提供者
  • @DataConsumer 定义方法参数依赖类型为其他接口返回值, 其他接口是一个@DataProvider
  • @InvokeParameter 定义方法参数依赖类型为用户输入值

3. 查询

通过 DataFacade.get 静态门面查询指定数据

示例

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

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

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

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

博客列表服务

需要参数userId

@Service
public class PostServiceImpl implements PostService {
    @DataProvider("posts")
    @Override
    public List<Post> getPosts(@InvokeParameter("userId") Long userId) {

用户基础信息查询服务

需要参数userId

@Service
public class UserServiceImpl implements UserService {
    @DataProvider("user")
    @Override
    public User get(@InvokeParameter("userId") Long id) {

2. 调用聚合接口

方式一: 函数式调用

注意这里不能将函数式调用改为Lambda表达式, 两者的实际行为是不一致的.

User user = DataFacade.get(
     Collections.singletonMap("userId", 1L), 
     new Function2<User, List<Post>, User>() {
            @Override
            public User apply(@DataConsumer("user") User user, 
                              @DataConsumer("posts") List<Post> posts) {
                user.setPosts(posts);
                return user;
            }
     });
Assert.notNull(user,"User must not be NULL");
Assert.notNull(user.getPosts(),"User's posts must not be NULL");

方式二: 定义聚合层查询

组合@DataProvider \ @DataConsumer \ @InvokeParameter 实现汇聚功能

@Component
public class UserAggregate {
    @DataProvider("userWithPosts")
    public User userWithPosts(
            @DataConsumer("user") User user,
            @DataConsumer("posts") List<Post> posts) {
        user.setPosts(posts);
        return user;
    }
}

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

User user = DataFacade.get(/*data id*/ "userWithPosts",
                            /*Invoke Parameters*/
                            Collections.singletonMap("userId",1L), 
                            User.class);
Assert.notNull(user,"User must not be NULL");
Assert.notNull(user.getPosts(),"User's posts must not be NULL");

运行结果

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

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

贡献者

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].