Closed
Description
需求建议
重构扩展点(SPI)功能
现有的扩展点的注册和使用都是通过ServiceLoader实现.
(cn.hippo4j.common.spi.DynamicThreadPoolServiceLoader)
有什么问题:
- 每次使用前都要去关注是否注册到了register map中.
- 由于一个扩展点接口可能拥有多个实现, 需要写很多冗余的代码去触发和判断List当中是否有满足条件的结果.
怎么解决:
注册的问题 - 结合spring
在Spring启动时, 扫描容器中所有被打上@Realization
(表示扩展点的实现类) 注解的 Bean, 并注册到ExtensionRegistry当中, 是一个 Map<Class<?>, List> extensionMap (扩展点接口类 <-> 扩展点实现list) 的注册表.
使用时, 通过调用的扩展点接口类, 在注册表当中找到对应的实现类对象List.
结果处理的问题 - 引入结果规约处理器Reducer
Reducer本质上是一个DataCollector, 通过统一的ExtensionInvoker触发器, 传入扩展点接口class, callback行为, 和一个Reducer.
触发代码可能如下: (比如场景是想找到第一个结果为非空的MyObject对象)
MyObject result = ExtensionInvoker.reduceExecute
(ITestExtension.class, ITestExtension::foo, request, Reducers.firstOf(Objects::nonNull));
函数原型:
public static <T extends IExtension, E, R> R reduceExecute(Class<T> targetClz, ExtensionCallback<T, E> callback,
Reducer<T, E, R> reducer);
这样我们就可以通过一行代码干净的解决扩展注册/寻找和结果处理的问题
规约函数, 可能出现如下几种类型:
- ResultObj FirstOf(Predicate p) -- 第一个遇到结果满足p的, 直接返回
- Boolean AllMatch(Predicate p) -- 判断执行结果是否都满足p
- Boolean AnyMatch(Predicate p) -- 判断任一执行结果是否满足p
- .... 可以继续扩展规约函数 (FlatMap, FlatList 等等)