有了自定义注解,使用变的非常方便:
@Datapublic class OrderListVOAnnV2 extends OrderListVO {private final OrderVO order;// 只需配置参数即可,其他配置由 JoinUserVOOnId 进行管理@JoinUserVOOnId(keyFromSourceData = https://www.isolves.com/it/cxkf/jiagou/2023-12-14/"#{order.userId}")private UserVO user;}@Datapublic class OrderDetailVOAnnV2 extends OrderDetailVO {private final OrderVO order;// 只需配置参数即可,其他配置由 JoinUserVOOnId 进行管理@JoinUserVOOnId(keyFromSourceData = "#{order.userId}")private UserVO user;}其他使用方式不变,但实现了逻辑简化:
- 新增绑定数据,只需自定义绑定注解
- VO 需新的绑定数据 , 只需在属性上添加绑定注解
@Data@JoinInMemoryConfig(executorType = JoinInMemeoryExecutorType.PARALLEL)public class OrderListVOAnnV3 extends OrderListVO {private final OrderVO order;@JoinUserVOOnId(keyFromSourceData = https://www.isolves.com/it/cxkf/jiagou/2023-12-14/"#{order.userId}")private UserVO user;@JoinAddressVOOnId(keyFromSourceData = "#{order.addressId}")private AddressVO address;@JoinProductVOOnId(keyFromSourceData = "#{order.productId}")private ProductVO product;}JoinInMemoryConfig 配置如下:
文章插图
6. 最佳实践6.1.将定义注解视为最佳实践@JoinInMemory 注解上配置的信息太多,如果直接在业务代码中使用 , 非常难以维护,当每个配置发生变化后,很难一次性修改到位 。所以,建议只将他作为“原注解”使用 。
整体思路详见:

文章插图
6.2. 注意线程池隔离对于不同的数据绑定需求,建议使用不同的线程池,从资源层面对不同功能进行隔离,从而将由于依赖接口发生阻塞导致线程耗尽所造成的影响控制在最小范围 。
@JoinInMemoryConfig 的 executorName 属性配置的便是执行器名称,不配置直接使用 “defaultExecutor” , 具体代码如下:
@Beanpublic ExecutorService defaultExecutor(){BasicThreadFactory basicThreadFactory = new BasicThreadFactory.Builder().namingPattern("JoinInMemory-Thread-%d").daemon(true).build();int maxSize = Runtime.getRuntime().availableProcessors() * 3;return new ThreadPoolExecutor(0, maxSize,60L, TimeUnit.SECONDS,new SynchronousQueue<>(),basicThreadFactory,new ThreadPoolExecutor.CallerRunsPolicy());}如需使用自定义线程池需:- 自定义线程池,并将其注册到Spring 容器
- @JoinInMemoryConfig executorName 设置为线程池的 bean name
- 今天面对的问题是:如何在应用成进行数据 Join 操作;
- 我们以我的订单和订单详情两个接口为业务切入点,层层进行抽象 , 发现变化、封装变化、管理变化
- 首先是手写代码,包括 foreach+单条抓?。??坎檠?内存Join,并行查询 + 内存Join 。在这个层次基本没有抽象可言,存在大量重复代码,系统扩展性低
- 其次是 Fetcher方案 , 为了分离“变化”与“不变”抽取出 Fetcher 和 FetcherExecutor 两个接口,并使用模板方法和责任链模式对其进行抽象,提升系统的扩展性,但实现过于繁琐不便于推广
- 最后是注解方案 , 使用 @JoinInMemory 注解完成繁琐的配置工作 , 将通用配置保留在自定义注解进行统一管理,基于 @AliasFor 完成入参的配置,还可以使用 @JoinInMemoryConfig 开启并发处理
推荐阅读
- 能如何看电脑内存,如何查看电脑c盘和d盘内存
- 你知道怎样在 Python 中管理内存吗
- 如何查看手机运行内存大小,如何查看手机软件占用的内存
- 能咋滴看电脑内存,怎么查看自己电脑内存多大
- sd卡和内存卡有什么区别
- 电脑能插3根内存条,电脑能咋滴共存两个窗口
- 苹果手机怎么在电脑上清理内存,苹果手机怎样可以清理内存拉圾
- oppo reno ace能插内存卡吗
- 手机内存满了该怎么处理,手机里照片太多,占内存太多该怎么办?
- 能咋地看电脑内存,如何查看电脑的内存条型号大小
