Spring Boot 高效数据聚合之道 (2)

首先, 我们先定义一个聚合接口

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

其中

@DataProvider 表示这个方法是一个数据提供者, 数据Id为 userFullData

@DataConsumer 表示这个方法的参数, 需要消费数据, 数据Id为 user ,posts, followers.

当然, 原来的3个原子服务 用户基础信息 ,用户博客列表, 用户的粉丝数据, 也分别需要添加一些注解

@Service public class UserServiceImpl implements UserService { @DataProvider(id = "user") @Override public User get(@InvokeParameter("userId") Long id) { @Service public class PostServiceImpl implements PostService { @DataProvider(id = "posts") @Override public List<Post> getPosts(@InvokeParameter("userId") Long userId) { @Service public class FollowServiceImpl implements FollowService { @DataProvider(id = "followers") @Override public List<User> getFollowers(@InvokeParameter("userId") Long userId) {

其中

@DataProvider 与前面的含义相同, 表示这个方法是一个数据提供者

@InvokeParameter 表示方法执行时, 需要手动传入的参数

这里注意 @InvokeParameter 和 @DataConsumer的区别, 前者需要用户在最上层调用时手动传参; 而后者, 是由框架自动分析依赖, 并异步调用取得结果之后注入的.

最后, 仅仅只需要调用一个统一的门面(Facade)接口, 传递数据Id, Invoke Parameters,以及返回值类型. 剩下的并行处理, 依赖分析和注入, 完全由框架自动处理.

@Component public class UserQueryFacade { @Autowired private DataBeanAggregateQueryFacade dataBeanAggregateQueryFacade; public User getUserFinal(Long userId) throws InterruptedException, IllegalAccessException, InvocationTargetException { return dataBeanAggregateQueryFacade.get("userFullData", Collections.singletonMap("userId", userId), User.class); } } 如何用在你的项目中

上面的功能, 笔者已经封装为一个spring boot starter, 并发布到maven中央仓库.

只需在你的项目引入依赖.

<dependency> <groupId>io.github.lvyahui8</groupId> <artifactId>spring-boot-data-aggregator-example</artifactId> <version>1.0.1</version> </dependency>

并在 application.properties 文件中声明注解的扫描路径.

# 替换成你需要扫描注解的包 io.github.lvyahui8.spring.base-packages=io.github.lvyahui8.spring.example

之后, 就可以使用如下注解和 Spring Bean 实现聚合查询

@DataProvider

@DataConsumer

@InvokeParameter

Spring Bean DataBeanAggregateQueryFacade

注意, @DataConsumer 和 @InvokeParameter 可以混合使用, 可以用在同一个方法的不同参数上. 且方法的所有参数必须有其中一个注解, 不能有没有注解的参数.

项目地址和上述示例代码: https://github.com/lvyahui8/spring-boot-data-aggregator

后期计划

后续笔者将继续完善异常处理, 超时逻辑, 解决命名冲突的问题, 并进一步提高插件的易用性, 高可用性, 扩展性

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfypf.html